NeoMutt  2018-07-16 +952-a2da0a
Teaching an old dog new tricks
DOXYGEN
mutt_logging.c File Reference

Mutt Logging. More...

#include "config.h"
#include <errno.h>
#include <limits.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include <time.h>
#include "mutt/mutt.h"
#include "curs_lib.h"
#include "globals.h"
#include "mutt_curses.h"
#include "mutt_window.h"
#include "muttlib.h"
#include "options.h"
+ Include dependency graph for mutt_logging.c:

Go to the source code of this file.

Macros

#define S_TO_NS   1000000000UL
 
#define S_TO_US   1000000UL
 
#define US_TO_NS   1000UL
 

Functions

static long micro_elapsed (const struct timeval *begin, const struct timeval *end)
 Number of microseconds between two timevals. More...
 
static void error_pause (void)
 Wait for an error message to be read. More...
 
static const char * rotate_logs (const char *file, int count)
 Rotate a set of numbered files. More...
 
void mutt_clear_error (void)
 Clear the message line (bottom line of screen) More...
 
int log_disp_curses (time_t stamp, const char *file, int line, const char *function, int level,...)
 Display a log line in the message line - Implements log_dispatcher_t. More...
 
void mutt_log_prep (void)
 Prepare to log. More...
 
void mutt_log_stop (void)
 Close the log file. More...
 
int mutt_log_set_file (const char *file, bool verbose)
 Change the logging file. More...
 
int mutt_log_set_level (int level, bool verbose)
 Change the logging level. More...
 
int mutt_log_start (void)
 Enable file logging. More...
 
int level_validator (const struct ConfigSet *cs, const struct ConfigDef *cdef, intptr_t value, struct Buffer *err)
 Validate the "debug_level" config variable. More...
 
bool mutt_log_listener (const struct ConfigSet *cs, struct HashElem *he, const char *name, enum ConfigEvent ev)
 Listen for config changes affecting the log file - Implements cs_listener() More...
 

Variables

struct timeval LastError = { 0 }
 
short DebugLevel = 0
 Config: Logging level for debug logs. More...
 
char * DebugFile = NULL
 Config: File to save debug logs. More...
 
char * CurrentFile = NULL
 The previous log file name. More...
 
const int NumOfLogs = 5
 How many log files to rotate. More...
 

Detailed Description

Mutt Logging.

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 mutt_logging.c.

Macro Definition Documentation

#define S_TO_NS   1000000000UL

Definition at line 53 of file mutt_logging.c.

#define S_TO_US   1000000UL

Definition at line 54 of file mutt_logging.c.

#define US_TO_NS   1000UL

Definition at line 55 of file mutt_logging.c.

Function Documentation

static long micro_elapsed ( const struct timeval *  begin,
const struct timeval *  end 
)
static

Number of microseconds between two timevals.

Parameters
beginBegin time
endEnd time
Return values
numMicroseconds elapsed
LONG_MAXBegin time was zero

Definition at line 64 of file mutt_logging.c.

65 {
66  if ((begin->tv_sec == 0) && (end->tv_sec != 0))
67  return LONG_MAX;
68 
69  return (end->tv_sec - begin->tv_sec) * S_TO_US + (end->tv_usec - begin->tv_usec);
70 }
#define S_TO_US
Definition: mutt_logging.c:54

+ Here is the caller graph for this function:

static void error_pause ( void  )
static

Wait for an error message to be read.

If '$sleep_time' seconds hasn't elapsed since LastError, then wait

Definition at line 77 of file mutt_logging.c.

78 {
79  struct timeval now = { 0 };
80 
81  if (gettimeofday(&now, NULL) < 0)
82  {
83  mutt_debug(1, "gettimeofday failed: %d\n", errno);
84  return;
85  }
86 
87  unsigned long sleep = SleepTime * S_TO_NS;
88  long micro = micro_elapsed(&LastError, &now);
89  if ((micro * US_TO_NS) >= sleep)
90  return;
91 
92  sleep -= (micro * US_TO_NS);
93 
94  struct timespec wait = {
95  .tv_sec = (sleep / S_TO_NS),
96  .tv_nsec = (sleep % S_TO_NS),
97  };
98 
99  mutt_refresh();
100  nanosleep(&wait, NULL);
101 }
#define S_TO_NS
Definition: mutt_logging.c:53
struct timeval LastError
Definition: mutt_logging.c:46
static long micro_elapsed(const struct timeval *begin, const struct timeval *end)
Number of microseconds between two timevals.
Definition: mutt_logging.c:64
time_t tv_sec
Definition: file.h:45
long tv_nsec
Definition: file.h:46
void mutt_refresh(void)
Force a refresh of the screen.
Definition: curs_lib.c:99
#define US_TO_NS
Definition: mutt_logging.c:55
Time value with nanosecond precision.
Definition: file.h:43
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
WHERE short SleepTime
Config: Time to pause after certain info messages.
Definition: globals.h:154

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static const char* rotate_logs ( const char *  file,
int  count 
)
static

Rotate a set of numbered files.

Parameters
fileTemplate filename
countMaximum number of files
Return values
ptrName of the 0'th file

Given a template 'temp', rename files numbered 0 to (count-1).

Rename:

  • ...
  • temp1 -> temp2
  • temp0 -> temp1

Definition at line 116 of file mutt_logging.c.

117 {
118  if (!file)
119  return NULL;
120 
121  char old[PATH_MAX];
122  char new[PATH_MAX];
123 
124  /* rotate the old debug logs */
125  for (count -= 2; count >= 0; count--)
126  {
127  snprintf(old, sizeof(old), "%s%d", file, count);
128  snprintf(new, sizeof(new), "%s%d", file, count + 1);
129 
130  mutt_expand_path(old, sizeof(old));
131  mutt_expand_path(new, sizeof(new));
132  rename(old, new);
133  }
134 
135  return mutt_str_strdup(old);
136 }
char * mutt_expand_path(char *buf, size_t buflen)
Create the canonical path.
Definition: muttlib.c:157
#define PATH_MAX
Definition: mutt.h:46
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:384

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void mutt_clear_error ( void  )

Clear the message line (bottom line of screen)

Definition at line 141 of file mutt_logging.c.

142 {
143  /* Make sure the error message has had time to be read */
144  if (OptMsgErr)
145  error_pause();
146 
147  ErrorBufMessage = false;
148  if (!OptNoCurses)
150 }
WHERE bool OptNoCurses
(pseudo) when sending in batch mode
Definition: options.h:45
void mutt_window_clearline(struct MuttWindow *win, int row)
Clear a row of a Window.
Definition: mutt_window.c:69
WHERE bool ErrorBufMessage
true if the last message was an error
Definition: globals.h:43
WHERE bool OptMsgErr
(pseudo) used by mutt_error/mutt_message
Definition: options.h:38
struct MuttWindow * MuttMessageWindow
Message Window.
Definition: mutt_window.c:41
static void error_pause(void)
Wait for an error message to be read.
Definition: mutt_logging.c:77

+ Here is the call graph for this function:

int log_disp_curses ( time_t  stamp,
const char *  file,
int  line,
const char *  function,
int  level,
  ... 
)

Display a log line in the message line - Implements log_dispatcher_t.

Definition at line 155 of file mutt_logging.c.

157 {
158  if (level > DebugLevel)
159  return 0;
160 
161  char buf[LONG_STRING];
162 
163  va_list ap;
164  va_start(ap, level);
165  const char *fmt = va_arg(ap, const char *);
166  int ret = vsnprintf(buf, sizeof(buf), fmt, ap);
167  va_end(ap);
168 
169  if (level == LL_PERROR)
170  {
171  char *buf2 = buf + ret;
172  int len = sizeof(buf) - ret;
173  char *p = strerror(errno);
174  if (!p)
175  p = _("unknown error");
176 
177  ret += snprintf(buf2, len, ": %s (errno = %d)", p, errno);
178  }
179 
180  const bool dupe = (strcmp(buf, ErrorBuf) == 0);
181  if (!dupe)
182  {
183  /* Only log unique messages */
184  log_disp_file(stamp, file, line, function, level, "%s", buf);
185  if (stamp == 0)
186  log_disp_queue(stamp, file, line, function, level, "%s", buf);
187  }
188 
189  /* Don't display debugging message on screen */
190  if (level > LL_MESSAGE)
191  return 0;
192 
193  /* Only pause if this is a message following an error */
194  if ((level > LL_ERROR) && OptMsgErr && !dupe)
195  error_pause();
196 
198  FMT_LEFT, 0, buf, sizeof(buf), 0);
199  ErrorBufMessage = true;
200 
201  if (!OptKeepQuiet)
202  {
203  if (level == LL_ERROR)
204  BEEP();
207  NORMAL_COLOR;
209  mutt_refresh();
210  }
211 
212  if ((level <= LL_ERROR) && !dupe)
213  {
214  OptMsgErr = true;
215  if (gettimeofday(&LastError, NULL) < 0)
216  mutt_debug(1, "gettimeofday failed: %d\n", errno);
217  }
218  else
219  {
220  OptMsgErr = false;
221  LastError.tv_sec = 0;
222  }
223 
224  return ret;
225 }
Log error.
Definition: logging.h:53
void mutt_simple_format(char *buf, size_t buflen, int min_width, int max_width, int justify, char pad_char, const char *s, size_t n, int arboreal)
Format a string, like snprintf()
Definition: curs_lib.c:911
#define NORMAL_COLOR
Definition: mutt_curses.h:235
void mutt_window_clrtoeol(struct MuttWindow *win)
Clear to the end of the line.
Definition: mutt_window.c:81
Log perror (using errno)
Definition: logging.h:52
short DebugLevel
Config: Logging level for debug logs.
Definition: mutt_logging.c:48
#define FMT_LEFT
Definition: curs_lib.h:41
#define _(a)
Definition: message.h:28
struct timeval LastError
Definition: mutt_logging.c:46
Log informational message.
Definition: logging.h:55
#define LONG_STRING
Definition: string2.h:36
WHERE char ErrorBuf[STRING]
Copy of the last error message.
Definition: globals.h:44
int log_disp_queue(time_t stamp, const char *file, int line, const char *function, int level,...)
Save a log line to an internal queue - Implements log_dispatcher_t.
Definition: logging.c:401
const char * line
Definition: common.c:35
void mutt_refresh(void)
Force a refresh of the screen.
Definition: curs_lib.c:99
Informational message.
Definition: mutt_curses.h:136
#define BEEP()
Definition: mutt_curses.h:79
WHERE bool ErrorBufMessage
true if the last message was an error
Definition: globals.h:43
int mutt_window_mvaddstr(struct MuttWindow *win, int row, int col, const char *str)
Move the cursor and write a fixed string to a Window.
Definition: mutt_window.c:190
#define SETCOLOR(X)
Definition: mutt_curses.h:220
int log_disp_file(time_t stamp, const char *file, int line, const char *function, int level,...)
Save a log line to a file.
Definition: logging.c:250
Error message.
Definition: mutt_curses.h:131
WHERE bool OptMsgErr
(pseudo) used by mutt_error/mutt_message
Definition: options.h:38
struct MuttWindow * MuttMessageWindow
Message Window.
Definition: mutt_window.c:41
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
static void error_pause(void)
Wait for an error message to be read.
Definition: mutt_logging.c:77
WHERE bool OptKeepQuiet
(pseudo) shut up the message and refresh functions while we are executing an external program...
Definition: options.h:36

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void mutt_log_prep ( void  )

Prepare to log.

Definition at line 230 of file mutt_logging.c.

231 {
232  char ver[64];
233  snprintf(ver, sizeof(ver), "-%s%s", PACKAGE_VERSION, GitVer);
235 }
void log_file_set_version(const char *version)
Set the program&#39;s version number.
Definition: logging.c:216
const char * GitVer

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void mutt_log_stop ( void  )

Close the log file.

Definition at line 240 of file mutt_logging.c.

241 {
242  log_file_close(false);
243  FREE(&CurrentFile);
244 }
void log_file_close(bool verbose)
Close the log file.
Definition: logging.c:97
char * CurrentFile
The previous log file name.
Definition: mutt_logging.c:50
#define FREE(x)
Definition: memory.h:46

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int mutt_log_set_file ( const char *  file,
bool  verbose 
)

Change the logging file.

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

Close the old log, rotate the new logs and open the new log.

Definition at line 255 of file mutt_logging.c.

256 {
258  {
259  const char *name = rotate_logs(DebugFile, NumOfLogs);
260  if (!name)
261  return -1;
262 
263  log_file_set_filename(name, false);
264  FREE(&name);
266  }
267 
268  cs_str_string_set(Config, "debug_file", file, NULL);
269 
270  return 0;
271 }
const int NumOfLogs
How many log files to rotate.
Definition: mutt_logging.c:51
int cs_str_string_set(const struct ConfigSet *cs, const char *name, const char *value, struct Buffer *err)
Set a config item by string.
Definition: set.c:657
char * CurrentFile
The previous log file name.
Definition: mutt_logging.c:50
WHERE struct ConfigSet * Config
Wrapper around the user&#39;s config settings.
Definition: globals.h:39
int log_file_set_filename(const char *file, bool verbose)
Set the filename for the log.
Definition: logging.c:147
char * DebugFile
Config: File to save debug logs.
Definition: mutt_logging.c:49
const char * name
Definition: pgpmicalg.c:42
void mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:460
#define FREE(x)
Definition: memory.h:46
static const char * rotate_logs(const char *file, int count)
Rotate a set of numbered files.
Definition: mutt_logging.c:116
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:612

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int mutt_log_set_level ( int  level,
bool  verbose 
)

Change the logging level.

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

Definition at line 280 of file mutt_logging.c.

281 {
282  if (!CurrentFile)
284 
285  if (log_file_set_level(level, verbose) != 0)
286  return -1;
287 
288  cs_str_native_set(Config, "debug_level", level, NULL);
289  return 0;
290 }
int mutt_log_set_file(const char *file, bool verbose)
Change the logging file.
Definition: mutt_logging.c:255
char * CurrentFile
The previous log file name.
Definition: mutt_logging.c:50
WHERE struct ConfigSet * Config
Wrapper around the user&#39;s config settings.
Definition: globals.h:39
char * DebugFile
Config: File to save debug logs.
Definition: mutt_logging.c:49
int log_file_set_level(int level, bool verbose)
Set the logging level.
Definition: logging.c:170
int cs_str_native_set(const struct ConfigSet *cs, const char *name, intptr_t value, struct Buffer *err)
Natively set the value of a string config item.
Definition: set.c:800

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int mutt_log_start ( void  )

Enable file logging.

Return values
0Success, or already running
-1Failed to start

This also handles file rotation.

Definition at line 299 of file mutt_logging.c.

300 {
301  if (DebugLevel < 1)
302  return 0;
303 
304  if (log_file_running())
305  return 0;
306 
308 
309  /* This will trigger the file creation */
310  if (log_file_set_level(DebugLevel, true) < 0)
311  return -1;
312 
313  return 0;
314 }
int mutt_log_set_file(const char *file, bool verbose)
Change the logging file.
Definition: mutt_logging.c:255
short DebugLevel
Config: Logging level for debug logs.
Definition: mutt_logging.c:48
char * DebugFile
Config: File to save debug logs.
Definition: mutt_logging.c:49
bool log_file_running(void)
Is the log file running?
Definition: logging.c:225
int log_file_set_level(int level, bool verbose)
Set the logging level.
Definition: logging.c:170

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int level_validator ( const struct ConfigSet cs,
const struct ConfigDef cdef,
intptr_t  value,
struct Buffer err 
)

Validate the "debug_level" config variable.

Parameters
csConfig items
cdefConfig definition
valueNative value
errMessage for the user
Return values
CSR_SUCCESSSuccess
CSR_ERR_INVALIDFailure

Definition at line 325 of file mutt_logging.c.

327 {
328  if ((value < 0) || (value > LL_DEBUG5))
329  {
330  mutt_buffer_printf(err, _("Invalid value for option %s: %ld"), cdef->name, value);
331  return CSR_ERR_INVALID;
332  }
333 
334  return CSR_SUCCESS;
335 }
#define _(a)
Definition: message.h:28
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:200
const char * name
User-visible name.
Definition: set.h:162
#define CSR_SUCCESS
Action completed successfully.
Definition: set.h:45
#define CSR_ERR_INVALID
Value hasn&#39;t been set.
Definition: set.h:48
Log at debug level 5.
Definition: logging.h:60

+ Here is the call graph for this function:

bool mutt_log_listener ( const struct ConfigSet cs,
struct HashElem he,
const char *  name,
enum ConfigEvent  ev 
)

Listen for config changes affecting the log file - Implements cs_listener()

Definition at line 340 of file mutt_logging.c.

342 {
343  if (mutt_str_strcmp(name, "debug_file") == 0)
345  else if (mutt_str_strcmp(name, "debug_level") == 0)
347 
348  return true;
349 }
int mutt_log_set_file(const char *file, bool verbose)
Change the logging file.
Definition: mutt_logging.c:255
short DebugLevel
Config: Logging level for debug logs.
Definition: mutt_logging.c:48
char * DebugFile
Config: File to save debug logs.
Definition: mutt_logging.c:49
const char * name
Definition: pgpmicalg.c:42
int mutt_log_set_level(int level, bool verbose)
Change the logging level.
Definition: mutt_logging.c:280
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:612

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Variable Documentation

struct timeval LastError = { 0 }

Definition at line 46 of file mutt_logging.c.

short DebugLevel = 0

Config: Logging level for debug logs.

Definition at line 48 of file mutt_logging.c.

char* DebugFile = NULL

Config: File to save debug logs.

Definition at line 49 of file mutt_logging.c.

char* CurrentFile = NULL

The previous log file name.

Definition at line 50 of file mutt_logging.c.

const int NumOfLogs = 5

How many log files to rotate.

Definition at line 51 of file mutt_logging.c.