cscvs to tla changeset 58
[onak.git] / log.c
1 /*
2  * log.c - Simple logging framework.
3  *
4  * Jonathan McDowell <noodles@earth.li>
5  *
6  * Copyright 2003 Project Purple
7  */
8
9 #include <stdarg.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <time.h>
14 #include <unistd.h>
15
16 #include "log.h"
17
18 /*
19  *      logthres - holds the minimum log level we'll output
20  *
21  *      This variable keeps track of the threshold we've set for outputting
22  *      logs - if we're asked to log something below this level we won't output
23  *      it.
24  */
25 static loglevels logthres = LOGTHING_DEBUG;
26
27 /*
28  *      logappname - the name of the application using us.
29  *
30  *      This holds information about the name of the application we're being
31  *      called by. It's set when we're initialized.
32  */
33 static char *logappname = NULL;
34
35 /*
36  *      logfilename - the file to log to.
37  *
38  *      The full name and path of the file we should log to.
39  */
40 static char *logfilename = NULL;
41
42 /*
43  *      initlogthing - initialize the logging module
44  *      @appname: The application name to use in the log.
45  *      @filename: The filename to log to. NULL means stderr.
46  *
47  *      This function sets up the logging module ready to log. The appname is
48  *      written as part of every log entry and the filename is the file we
49  *      should log to. If the appname is NULL then none is written. If the
50  *      filename is NULL all output is sent to stderr.
51  */
52 int initlogthing(const char *appname, const char *filename)
53 {
54         if (appname != NULL) {
55                 logappname = strdup(appname);
56         }
57
58         if (filename != NULL) {
59                 logfilename = strdup(filename);
60         }
61
62         return 0;
63 }
64
65 /*
66  *      cleanuplogthing - clean up the logging module
67  *
68  *      This function cleans up the logging module after use.
69  */
70 void cleanuplogthing(void)
71 {
72         if (logappname != NULL) {
73                 free(logappname);
74                 logappname = NULL;
75         }
76
77         if (logfilename != NULL) {
78                 free(logfilename);
79                 logfilename = NULL;
80         }
81
82         return;
83 }
84
85 /*
86  *      setlogthreshold - set the threshold for log output
87  *      @loglevel: The minimum log level we should output
88  *
89  *      Sets the threshold for log output; anything logged with a log level
90  *      lower than this will be silently dropped. Returns the old log threshold
91  *      value.
92  */
93 loglevels setlogthreshold(loglevels loglevel)
94 {
95         loglevels oldlevel;
96
97         oldlevel = logthres;
98         logthres = loglevel;
99
100         return oldlevel;
101 }
102
103 /*
104  *      logthing - output a log entry
105  *      @loglevel: The level of the log.
106  *      @format: A format string, followed by any parameters required.
107  *
108  *      This function outputs a log entry. A leading time/date stamp and a
109  *      trailing newline are automatically added. The loglevel is compared to
110  *      the current log threshold and if equal or above the log entry is
111  *      output. The format parameter is of the same nature as that used in
112  *      printf.
113  */
114 int logthing(loglevels loglevel, const char *format, ...)
115 {
116         FILE      *logfile = NULL;
117         struct tm *timestamp = NULL;
118         time_t     timer = 0;
119         va_list    ap;
120
121         if (loglevel >= logthres) {
122                 timer = time(NULL);
123                 timestamp = localtime(&timer);
124
125                 if (logfilename != NULL) {
126                         logfile = fopen(logfilename, "a");
127                         flockfile(logfile);
128                 } else {
129                         logfile = stderr;
130                 }
131         
132                 fprintf(logfile, "[%02d/%02d/%4d %02d:%02d:%02d] %s[%d]: ",
133                                 timestamp->tm_mday,
134                                 timestamp->tm_mon,
135                                 timestamp->tm_year + 1900,
136                                 timestamp->tm_hour,
137                                 timestamp->tm_min,
138                                 timestamp->tm_sec,
139                                 (logappname == NULL) ? "" : logappname,
140                                 getpid());
141                 va_start(ap, format);
142                 vfprintf(logfile, format, ap);
143                 va_end(ap);
144                 fprintf(logfile, "\n");
145
146
147                 if (logfilename != NULL) {
148                         funlockfile(logfile);
149                         fclose(logfile);
150                         logfile = NULL;
151                 }
152         }
153
154         return 0;
155 }