2 * copyright (c) 2007 Emil Mikulic.
4 * daylog.c: daily usage log
6 * You may use, modify and redistribute this file under the terms of the
7 * GNU General Public License version 2. (see COPYING.GPL)
10 #define _GNU_SOURCE 1 /* for O_NOFOLLOW on Linux */
12 #include <sys/types.h>
25 static const char *daylog_fn
= NULL
;
26 static time_t today_time
, tomorrow_time
;
27 static uint64_t bytes_in
, bytes_out
, pkts_in
, pkts_out
;
29 #define DAYLOG_DATE_LEN 26 /* strlen("1900-01-01 00:00:00 +1234") + 1 */
30 static char datebuf
[DAYLOG_DATE_LEN
];
33 fmt_date(const time_t when
)
36 if (strftime(datebuf
, DAYLOG_DATE_LEN
,
37 "%Y-%m-%d %H:%M:%S %z", localtime(&tmp
) ) == 0)
38 errx(1, "strftime() failed in fmt_date()");
42 /* Given some time today, find the first second of tomorrow. */
44 tomorrow(const time_t today
)
50 memcpy(&tm
, lt
, sizeof(tm
));
54 tm
.tm_mday
= lt
->tm_mday
+ 1; /* tomorrow */
61 return open(daylog_fn
, O_WRONLY
| O_APPEND
| O_CREAT
| O_NOFOLLOW
, 0600);
67 int fd
= daylog_open();
70 struct str
*buf
= str_make();
73 str_appendf(buf
, "%s|%u|%qu|%qu|%qu|%qu\n",
74 fmt_date(today_time
), (unsigned int)today_time
,
75 bytes_in
, bytes_out
, pkts_in
, pkts_out
);
76 str_extract(buf
, &len
, &s
);
78 (void)write(fd
, s
, len
); /* ignore write errors */
85 daylog_init(const char *filename
)
93 today_time
= time(NULL
);
94 tomorrow_time
= tomorrow(today_time
);
95 verbosef("today is %u, tomorrow is %u",
96 (unsigned int)today_time
, (unsigned int)tomorrow_time
);
97 bytes_in
= bytes_out
= pkts_in
= pkts_out
= 0;
101 err(1, "couldn't open(\"%s\") for append", filename
);
104 str_appendf(buf
, "# logging started at %s (%u)\n",
105 fmt_date(today_time
), (unsigned int)today_time
);
106 str_extract(buf
, &len
, &s
);
107 (void)write(fd
, s
, len
); /* ignore write errors */
112 void daylog_free(void)
119 today_time
= time(NULL
);
121 /* Emit what's currently accumulated. */
125 if (fd
== -1) return;
128 str_appendf(buf
, "# logging stopped at %s (%u)\n",
129 fmt_date(today_time
), (unsigned int)today_time
);
130 str_extract(buf
, &len
, &s
);
131 (void)write(fd
, s
, len
); /* ignore write errors */
137 daylog_acct(uint64_t amount
, enum graph_dir dir
)
139 if (daylog_fn
== NULL
) return; /* disabled */
141 /* Check if we need to rotate. */
142 if (now
>= tomorrow_time
) {
146 tomorrow_time
= tomorrow(today_time
);
147 bytes_in
= bytes_out
= pkts_in
= pkts_out
= 0;
148 verbosef("rotated daylog, tomorrow = %u",
149 (unsigned int)tomorrow_time
);
153 if (dir
== GRAPH_IN
) {
157 assert(dir
== GRAPH_OUT
);
163 /* vim:set ts=3 sw=3 tw=78 et: */