a0b517ea99a52b772484e08fa391f8a8a45baab4
2 * copyright (c) 2007-2011 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>
24 static const char *daylog_fn
= NULL
;
25 static time_t today_time
, tomorrow_time
;
26 static uint64_t bytes_in
, bytes_out
, pkts_in
, pkts_out
;
28 #define DAYLOG_DATE_LEN 26 /* strlen("1900-01-01 00:00:00 +1234") + 1 */
29 static char datebuf
[DAYLOG_DATE_LEN
];
32 fmt_date(const time_t when
)
35 if (strftime(datebuf
, DAYLOG_DATE_LEN
,
36 "%Y-%m-%d %H:%M:%S %z", localtime(&tmp
) ) == 0)
37 errx(1, "strftime() failed in fmt_date()");
41 /* Given some time today, find the first second of tomorrow. */
43 tomorrow(const time_t today
)
49 memcpy(&tm
, lt
, sizeof(tm
));
53 tm
.tm_mday
= lt
->tm_mday
+ 1; /* tomorrow */
60 return open(daylog_fn
, O_WRONLY
| O_APPEND
| O_CREAT
| O_NOFOLLOW
, 0600);
66 int fd
= daylog_open();
69 struct str
*buf
= str_make();
72 str_appendf(buf
, "%s|%u|%qu|%qu|%qu|%qu\n",
73 fmt_date(today_time
), (unsigned int)today_time
,
74 bytes_in
, bytes_out
, pkts_in
, pkts_out
);
75 str_extract(buf
, &len
, &s
);
77 (void)write(fd
, s
, len
); /* ignore write errors */
84 daylog_init(const char *filename
)
92 today_time
= time(NULL
);
93 tomorrow_time
= tomorrow(today_time
);
94 verbosef("today is %u, tomorrow is %u",
95 (unsigned int)today_time
, (unsigned int)tomorrow_time
);
96 bytes_in
= bytes_out
= pkts_in
= pkts_out
= 0;
100 err(1, "couldn't open(\"%s\") for append", filename
);
103 str_appendf(buf
, "# logging started at %s (%u)\n",
104 fmt_date(today_time
), (unsigned int)today_time
);
105 str_extract(buf
, &len
, &s
);
106 (void)write(fd
, s
, len
); /* ignore write errors */
111 void daylog_free(void)
118 today_time
= time(NULL
);
120 /* Emit what's currently accumulated. */
124 if (fd
== -1) return;
127 str_appendf(buf
, "# logging stopped at %s (%u)\n",
128 fmt_date(today_time
), (unsigned int)today_time
);
129 str_extract(buf
, &len
, &s
);
130 (void)write(fd
, s
, len
); /* ignore write errors */
136 daylog_acct(uint64_t amount
, enum graph_dir dir
)
138 if (daylog_fn
== NULL
) return; /* disabled */
140 /* Check if we need to rotate. */
141 if (now
>= tomorrow_time
) {
145 tomorrow_time
= tomorrow(today_time
);
146 bytes_in
= bytes_out
= pkts_in
= pkts_out
= 0;
147 verbosef("rotated daylog, tomorrow = %u",
148 (unsigned int)tomorrow_time
);
152 if (dir
== GRAPH_IN
) {
156 assert(dir
== GRAPH_OUT
);
162 /* vim:set ts=3 sw=3 tw=78 et: */