NeoMutt
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
logging2.h File Reference

Logging Dispatcher. More...

#include <stdbool.h>
#include <stdio.h>
#include <time.h>
#include "queue.h"
+ Include dependency graph for logging2.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  LogLine
 A Log line. More...
 

Macros

#define LOG_LINE_MAX_LEN   10240
 Log lines longer than this will be truncated.
 
#define mutt_debug(LEVEL, ...)   MuttLogger(0, __FILE__, __LINE__, __func__, LEVEL, __VA_ARGS__)
 
#define mutt_warning(...)   MuttLogger(0, __FILE__, __LINE__, __func__, LL_WARNING, __VA_ARGS__)
 
#define mutt_message(...)   MuttLogger(0, __FILE__, __LINE__, __func__, LL_MESSAGE, __VA_ARGS__)
 
#define mutt_error(...)   MuttLogger(0, __FILE__, __LINE__, __func__, LL_ERROR, __VA_ARGS__)
 
#define mutt_perror(...)   MuttLogger(0, __FILE__, __LINE__, __func__, LL_PERROR, __VA_ARGS__)
 

Typedefs

typedef int(* log_dispatcher_t) (time_t stamp, const char *file, int line, const char *function, enum LogLevel level, const char *format,...) __attribute__((__format__(__printf__
 
typedef int(*) log_dispatcher_ MuttLogger)
 

Enumerations

enum  LogLevel {
  LL_PERROR = -3 , LL_ERROR = -2 , LL_WARNING = -1 , LL_MESSAGE = 0 ,
  LL_DEBUG1 = 1 , LL_DEBUG2 = 2 , LL_DEBUG3 = 3 , LL_DEBUG4 = 4 ,
  LL_DEBUG5 = 5 , LL_NOTIFY = 6 , LL_MAX
}
 Names for the Logging Levels. More...
 

Functions

 STAILQ_HEAD (LogLineList, LogLine)
 
int log_disp_file (time_t stamp, const char *file, int line, const char *function, enum LogLevel level, const char *format,...) __attribute__((__format__(__printf__
 
int int log_disp_null (time_t stamp, const char *file, int line, const char *function, enum LogLevel level, const char *format,...) __attribute__((__format__(__printf__
 
int int int log_disp_queue (time_t stamp, const char *file, int line, const char *function, enum LogLevel level, const char *format,...) __attribute__((__format__(__printf__
 
int int int int log_disp_terminal (time_t stamp, const char *file, int line, const char *function, enum LogLevel level, const char *format,...) __attribute__((__format__(__printf__
 
int int int int int log_queue_add (struct LogLine *ll)
 Add a LogLine to the queue.
 
void log_queue_empty (void)
 Free the contents of the queue.
 
void log_queue_flush (log_dispatcher_t disp)
 Replay the log queue.
 
int log_queue_save (FILE *fp)
 Save the contents of the queue to a temporary file.
 
void log_queue_set_max_size (int size)
 Set a upper limit for the queue length.
 
void log_file_close (bool verbose)
 Close the log file.
 
int log_file_open (bool verbose)
 Start logging to a file.
 
bool log_file_running (void)
 Is the log file running?
 
int log_file_set_filename (const char *file, bool verbose)
 Set the filename for the log.
 
int log_file_set_level (enum LogLevel level, bool verbose)
 Set the logging level.
 
void log_file_set_version (const char *version)
 Set the program's version number.
 

Detailed Description

Logging Dispatcher.

Authors
  • Richard Russon

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Definition in file logging2.h.

Macro Definition Documentation

◆ LOG_LINE_MAX_LEN

#define LOG_LINE_MAX_LEN   10240

Log lines longer than this will be truncated.

Definition at line 32 of file logging2.h.

Typedef Documentation

◆ log_dispatcher_t

typedef int(* log_dispatcher_t) (time_t stamp, const char *file, int line, const char *function, enum LogLevel level, const char *format,...) __attribute__((__format__(__printf__

Definition at line 69 of file logging2.h.

◆ MuttLogger

typedef int(*) log_dispatcher_ MuttLogger)
extern

Enumeration Type Documentation

◆ LogLevel

enum LogLevel

Names for the Logging Levels.

Enumerator
LL_PERROR 

Log perror (using errno)

LL_ERROR 

Log error.

LL_WARNING 

Log warning.

LL_MESSAGE 

Log informational message.

LL_DEBUG1 

Log at debug level 1.

LL_DEBUG2 

Log at debug level 2.

LL_DEBUG3 

Log at debug level 3.

LL_DEBUG4 

Log at debug level 4.

LL_DEBUG5 

Log at debug level 5.

LL_NOTIFY 

Log of notifications.

LL_MAX 

Definition at line 37 of file logging2.h.

38{
39 LL_PERROR = -3,
40 LL_ERROR = -2,
41 LL_WARNING = -1,
42 LL_MESSAGE = 0,
43 LL_DEBUG1 = 1,
44 LL_DEBUG2 = 2,
45 LL_DEBUG3 = 3,
46 LL_DEBUG4 = 4,
47 LL_DEBUG5 = 5,
48 LL_NOTIFY = 6,
49
50 LL_MAX,
51};
@ LL_DEBUG4
Log at debug level 4.
Definition: logging2.h:46
@ LL_ERROR
Log error.
Definition: logging2.h:40
@ LL_DEBUG3
Log at debug level 3.
Definition: logging2.h:45
@ LL_PERROR
Log perror (using errno)
Definition: logging2.h:39
@ LL_DEBUG5
Log at debug level 5.
Definition: logging2.h:47
@ LL_WARNING
Log warning.
Definition: logging2.h:41
@ LL_MESSAGE
Log informational message.
Definition: logging2.h:42
@ LL_DEBUG2
Log at debug level 2.
Definition: logging2.h:44
@ LL_DEBUG1
Log at debug level 1.
Definition: logging2.h:43
@ LL_NOTIFY
Log of notifications.
Definition: logging2.h:48
@ LL_MAX
Definition: logging2.h:50

Function Documentation

◆ STAILQ_HEAD()

STAILQ_HEAD ( LogLineList  ,
LogLine   
)

◆ log_disp_file()

int log_disp_file ( time_t  stamp,
const char *  file,
int  line,
const char *  function,
enum LogLevel  level,
const char *  format,
  ... 
)

◆ log_disp_null()

int int log_disp_null ( time_t  stamp,
const char *  file,
int  line,
const char *  function,
enum LogLevel  level,
const char *  format,
  ... 
)

◆ log_disp_queue()

int int int log_disp_queue ( time_t  stamp,
const char *  file,
int  line,
const char *  function,
enum LogLevel  level,
const char *  format,
  ... 
)

◆ log_disp_terminal()

int int int int log_disp_terminal ( time_t  stamp,
const char *  file,
int  line,
const char *  function,
enum LogLevel  level,
const char *  format,
  ... 
)

◆ log_queue_add()

int int int int int log_queue_add ( struct LogLine ll)

Add a LogLine to the queue.

Parameters
llLogLine to add
Return values
numEntries in the queue

If LogQueueMax is non-zero, the queue will be limited to this many items.

Definition at line 284 of file logging.c.

285{
286 if (!ll)
287 return -1;
288
289 STAILQ_INSERT_TAIL(&LogQueue, ll, entries);
290
291 if ((LogQueueMax > 0) && (LogQueueCount >= LogQueueMax))
292 {
293 ll = STAILQ_FIRST(&LogQueue);
294 STAILQ_REMOVE_HEAD(&LogQueue, entries);
295 FREE(&ll->message);
296 FREE(&ll);
297 }
298 else
299 {
301 }
302 return LogQueueCount;
303}
static struct LogLineList LogQueue
In-memory list of log lines.
Definition: logging.c:62
static int LogQueueMax
Maximum number of entries in the log queue.
Definition: logging.c:65
static int LogQueueCount
Number of entries currently in the log queue.
Definition: logging.c:64
#define FREE(x)
Definition: memory.h:45
#define STAILQ_REMOVE_HEAD(head, field)
Definition: queue.h:422
#define STAILQ_FIRST(head)
Definition: queue.h:350
#define STAILQ_INSERT_TAIL(head, elm, field)
Definition: queue.h:389
char * message
Message to be logged.
Definition: logging2.h:84
+ Here is the caller graph for this function:

◆ log_queue_empty()

void log_queue_empty ( void  )

Free the contents of the queue.

Free any log lines in the queue.

Definition at line 323 of file logging.c.

324{
325 struct LogLine *ll = NULL;
326 struct LogLine *tmp = NULL;
327
328 STAILQ_FOREACH_SAFE(ll, &LogQueue, entries, tmp)
329 {
330 STAILQ_REMOVE(&LogQueue, ll, LogLine, entries);
331 FREE(&ll->message);
332 FREE(&ll);
333 }
334
335 LogQueueCount = 0;
336}
#define STAILQ_REMOVE(head, elm, type, field)
Definition: queue.h:402
#define STAILQ_FOREACH_SAFE(var, head, field, tvar)
Definition: queue.h:362
A Log line.
Definition: logging2.h:78
+ Here is the caller graph for this function:

◆ log_queue_flush()

void log_queue_flush ( log_dispatcher_t  disp)

Replay the log queue.

Parameters
dispLog dispatcher - Implements log_dispatcher_t

Pass all of the log entries in the queue to the log dispatcher provided. The queue will be emptied afterwards.

Definition at line 345 of file logging.c.

346{
347 struct LogLine *ll = NULL;
348 STAILQ_FOREACH(ll, &LogQueue, entries)
349 {
350 disp(ll->time, ll->file, ll->line, ll->function, ll->level, "%s", ll->message);
351 }
352
354}
void log_queue_empty(void)
Free the contents of the queue.
Definition: logging.c:323
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:352
const char * file
Source file.
Definition: logging2.h:80
const char * function
C function.
Definition: logging2.h:82
int line
Line number in source file.
Definition: logging2.h:81
enum LogLevel level
Log level, e.g. LL_DEBUG1.
Definition: logging2.h:83
time_t time
Timestamp of the message.
Definition: logging2.h:79
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ log_queue_save()

int log_queue_save ( FILE *  fp)

Save the contents of the queue to a temporary file.

Parameters
fpOpen file handle
Return values
numLines written to the file

The queue is written to a temporary file. The format is:

  • [HH:MM:SS]<LEVEL> FORMATTED-MESSAGE
Note
The caller should delete the file

Definition at line 366 of file logging.c.

367{
368 if (!fp)
369 return 0;
370
371 char buf[32] = { 0 };
372 int count = 0;
373 struct LogLine *ll = NULL;
374 STAILQ_FOREACH(ll, &LogQueue, entries)
375 {
376 mutt_date_localtime_format(buf, sizeof(buf), "%H:%M:%S", ll->time);
377 fprintf(fp, "[%s]<%c> %s", buf, LevelAbbr[ll->level + 3], ll->message);
378 if (ll->level <= LL_MESSAGE)
379 fputs("\n", fp);
380 count++;
381 }
382
383 return count;
384}
static const char * LevelAbbr
Abbreviations of logging level names.
Definition: logging.c:45
size_t mutt_date_localtime_format(char *buf, size_t buflen, const char *format, time_t t)
Format localtime.
Definition: date.c:924
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ log_queue_set_max_size()

void log_queue_set_max_size ( int  size)

Set a upper limit for the queue length.

Parameters
sizeNew maximum queue length
Note
size of 0 means unlimited

Definition at line 311 of file logging.c.

312{
313 if (size < 0)
314 size = 0;
315 LogQueueMax = size;
316}
+ Here is the caller graph for this function:

◆ log_file_close()

void log_file_close ( bool  verbose)

Close the log file.

Parameters
verboseIf true, then log the event

Definition at line 98 of file logging.c.

99{
100 if (!LogFileFP)
101 return;
102
103 fprintf(LogFileFP, "[%s] Closing log.\n", timestamp(0));
104 fprintf(LogFileFP, "# vim: syntax=neomuttlog\n");
106 if (verbose)
107 mutt_message(_("Closed log file: %s"), LogFileName);
108}
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:152
#define mutt_message(...)
Definition: logging2.h:91
static FILE * LogFileFP
Log file handle.
Definition: logging.c:54
static const char * timestamp(time_t stamp)
Create a YYYY-MM-DD HH:MM:SS timestamp.
Definition: logging.c:77
static char * LogFileName
Log file name.
Definition: logging.c:55
#define _(a)
Definition: message.h:28
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ log_file_open()

int log_file_open ( bool  verbose)

Start logging to a file.

Parameters
verboseIf true, then log the event
Return values
0Success
-1Error, see errno

Before opening a log file, call log_file_set_version(), log_file_set_level() and log_file_set_filename().

Definition at line 119 of file logging.c.

120{
121 if (!LogFileName)
122 return -1;
123
124 if (LogFileFP)
125 log_file_close(false);
126
128 return -1;
129
131 if (!LogFileFP)
132 return -1;
133 setvbuf(LogFileFP, NULL, _IOLBF, 0);
134
135 fprintf(LogFileFP, "[%s] NeoMutt%s debugging at level %d\n", timestamp(0),
137 if (verbose)
138 mutt_message(_("Debugging at level %d to file '%s'"), LogFileLevel, LogFileName);
139 return 0;
140}
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:636
static char * LogFileVersion
Program version.
Definition: logging.c:57
static int LogFileLevel
Log file level.
Definition: logging.c:56
void log_file_close(bool verbose)
Close the log file.
Definition: logging.c:98
#define NONULL(x)
Definition: string2.h:37
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ log_file_running()

bool log_file_running ( void  )

Is the log file running?

Return values
trueThe log file is running

Definition at line 229 of file logging.c.

230{
231 return LogFileFP;
232}
+ Here is the caller graph for this function:

◆ log_file_set_filename()

int log_file_set_filename ( const char *  file,
bool  verbose 
)

Set the filename for the log.

Parameters
fileName to use
verboseIf true, then log the event
Return values
0Success, file opened
-1Error, see errno

Definition at line 149 of file logging.c.

150{
151 if (!file)
152 return -1;
153
154 /* also handles both being NULL */
155 if (mutt_str_equal(LogFileName, file))
156 return 0;
157
159
160 if (!LogFileName)
161 log_file_close(verbose);
162
163 return log_file_open(verbose);
164}
int log_file_open(bool verbose)
Start logging to a file.
Definition: logging.c:119
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:798
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:327
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ log_file_set_level()

int log_file_set_level ( enum LogLevel  level,
bool  verbose 
)

Set the logging level.

Parameters
levelLogging level
verboseIf true, then log the event
Return values
0Success
-1Error, level is out of range

The level should be: LL_MESSAGE <= level < LL_MAX.

Definition at line 175 of file logging.c.

176{
177 if ((level < LL_MESSAGE) || (level >= LL_MAX))
178 return -1;
179
180 if (level == LogFileLevel)
181 return 0;
182
183 LogFileLevel = level;
184
185 if (level == LL_MESSAGE)
186 {
187 log_file_close(verbose);
188 }
189 else if (LogFileFP)
190 {
191 if (verbose)
192 mutt_message(_("Logging at level %d to file '%s'"), LogFileLevel, LogFileName);
193 fprintf(LogFileFP, "[%s] NeoMutt%s debugging at level %d\n", timestamp(0),
195 }
196 else
197 {
198 log_file_open(verbose);
199 }
200
201 if (LogFileLevel >= LL_DEBUG5)
202 {
203 fprintf(LogFileFP, "\n"
204 "WARNING:\n"
205 " Logging at this level can reveal personal information.\n"
206 " Review the log carefully before posting in bug reports.\n"
207 "\n");
208 }
209
210 return 0;
211}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ log_file_set_version()

void log_file_set_version ( const char *  version)

Set the program's version number.

Parameters
versionVersion number

The string will be appended directly to 'NeoMutt', so it should begin with a hyphen.

Definition at line 220 of file logging.c.

221{
223}
+ Here is the call graph for this function:
+ Here is the caller graph for this function: