NeoMutt  2021-02-05-666-ge300cd
Teaching an old dog new tricks
DOXYGEN
mutt_logging.c File Reference

NeoMutt Logging. More...

#include "config.h"
#include <errno.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "mutt/lib.h"
#include "config/lib.h"
#include "core/lib.h"
#include "gui/lib.h"
#include "mutt_logging.h"
#include "mutt_globals.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_MS   1000L
 

Functions

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, enum LogLevel 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 (enum LogLevel 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 - Implements ConfigDef::validator() -. More...
 
int main_log_observer (struct NotifyCallback *nc)
 Notification that a Config Variable has changed - Implements observer_t. More...
 

Variables

uint64_t LastError = 0
 Time of the last error message (in milliseconds since the Unix epoch) More...
 
char * CurrentFile = NULL
 The previous log file name. More...
 
const int NumOfLogs = 5
 How many log files to rotate. More...
 

Detailed Description

NeoMutt 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

◆ S_TO_MS

#define S_TO_MS   1000L

Definition at line 51 of file mutt_logging.c.

Function Documentation

◆ error_pause()

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 58 of file mutt_logging.c.

59 {
60  const short c_sleep_time = cs_subset_number(NeoMutt->sub, "sleep_time");
61  const uint64_t elapsed = mutt_date_epoch_ms() - LastError;
62  const uint64_t sleep = c_sleep_time * S_TO_MS;
63  if ((LastError == 0) || (elapsed >= sleep))
64  return;
65 
66  mutt_refresh();
67  mutt_date_sleep_ms(sleep - elapsed);
68 }
uint64_t mutt_date_epoch_ms(void)
Return the number of milliseconds since the Unix epoch.
Definition: date.c:436
uint64_t LastError
Time of the last error message (in milliseconds since the Unix epoch)
Definition: mutt_logging.c:46
short cs_subset_number(const struct ConfigSubset *sub, const char *name)
Get a number config item by name.
Definition: helpers.c:169
Container for Accounts, Notifications.
Definition: neomutt.h:36
void mutt_refresh(void)
Force a refresh of the screen.
Definition: curs_lib.c:115
#define S_TO_MS
Definition: mutt_logging.c:51
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
void mutt_date_sleep_ms(size_t ms)
Sleep for milliseconds.
Definition: date.c:704
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ rotate_logs()

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 83 of file mutt_logging.c.

84 {
85  if (!file)
86  return NULL;
87 
88  struct Buffer *old_file = mutt_buffer_pool_get();
89  struct Buffer *new_file = mutt_buffer_pool_get();
90 
91  /* rotate the old debug logs */
92  for (count -= 2; count >= 0; count--)
93  {
94  mutt_buffer_printf(old_file, "%s%d", file, count);
95  mutt_buffer_printf(new_file, "%s%d", file, count + 1);
96 
97  mutt_buffer_expand_path(old_file);
98  mutt_buffer_expand_path(new_file);
99  rename(mutt_buffer_string(old_file), mutt_buffer_string(new_file));
100  }
101 
102  file = mutt_buffer_strdup(old_file);
103  mutt_buffer_pool_release(&old_file);
104  mutt_buffer_pool_release(&new_file);
105 
106  return file;
107 }
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
char * mutt_buffer_strdup(const struct Buffer *buf)
Copy a Buffer&#39;s string.
Definition: buffer.c:432
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
String manipulation buffer.
Definition: buffer.h:33
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
void mutt_buffer_expand_path(struct Buffer *buf)
Create the canonical path.
Definition: muttlib.c:322
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_clear_error()

void mutt_clear_error ( void  )

Clear the message line (bottom line of screen)

Definition at line 112 of file mutt_logging.c.

113 {
114  /* Make sure the error message has had time to be read */
115  if (OptMsgErr)
116  error_pause();
117 
118  ErrorBufMessage = false;
119  if (!OptNoCurses)
121 }
WHERE bool OptNoCurses
(pseudo) when sending in batch mode
Definition: options.h:47
void msgwin_clear_text(void)
Clear the text in the Message Window.
Definition: msgwin.c:242
WHERE bool OptMsgErr
(pseudo) used by mutt_error/mutt_message
Definition: options.h:40
WHERE bool ErrorBufMessage
true if the last message was an error
Definition: mutt_globals.h:42
static void error_pause(void)
Wait for an error message to be read.
Definition: mutt_logging.c:58
+ Here is the call graph for this function:

◆ mutt_log_prep()

void mutt_log_prep ( void  )

Prepare to log.

Definition at line 211 of file mutt_logging.c.

212 {
213  char ver[64];
214  snprintf(ver, sizeof(ver), "-%s%s", PACKAGE_VERSION, GitVer);
216 }
void log_file_set_version(const char *version)
Set the program&#39;s version number.
Definition: logging.c:221
const char * GitVer
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_log_stop()

void mutt_log_stop ( void  )

Close the log file.

Definition at line 221 of file mutt_logging.c.

222 {
223  log_file_close(false);
224  FREE(&CurrentFile);
225 }
void log_file_close(bool verbose)
Close the log file.
Definition: logging.c:98
char * CurrentFile
The previous log file name.
Definition: mutt_logging.c:48
#define FREE(x)
Definition: memory.h:40
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_log_set_file()

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 236 of file mutt_logging.c.

237 {
238  const char *const c_debug_file = cs_subset_path(NeoMutt->sub, "debug_file");
239  if (!mutt_str_equal(CurrentFile, c_debug_file))
240  {
241  const char *name = rotate_logs(c_debug_file, NumOfLogs);
242  if (!name)
243  return -1;
244 
245  log_file_set_filename(name, false);
246  FREE(&name);
247  mutt_str_replace(&CurrentFile, c_debug_file);
248  }
249 
250  cs_subset_str_string_set(NeoMutt->sub, "debug_file", file, NULL);
251 
252  return 0;
253 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:904
const int NumOfLogs
How many log files to rotate.
Definition: mutt_logging.c:49
char * CurrentFile
The previous log file name.
Definition: mutt_logging.c:48
int log_file_set_filename(const char *file, bool verbose)
Set the filename for the log.
Definition: logging.c:149
Container for Accounts, Notifications.
Definition: neomutt.h:36
int cs_subset_str_string_set(const struct ConfigSubset *sub, const char *name, const char *value, struct Buffer *err)
Set a config item by string.
Definition: subset.c:408
const char * cs_subset_path(const struct ConfigSubset *sub, const char *name)
Get a path config item by name.
Definition: helpers.c:194
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:446
#define FREE(x)
Definition: memory.h:40
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
static const char * rotate_logs(const char *file, int count)
Rotate a set of numbered files.
Definition: mutt_logging.c:83
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_log_set_level()

int mutt_log_set_level ( enum LogLevel  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 262 of file mutt_logging.c.

263 {
264  if (!CurrentFile)
265  {
266  const char *const c_debug_file = cs_subset_path(NeoMutt->sub, "debug_file");
267  mutt_log_set_file(c_debug_file, false);
268  }
269 
270  if (log_file_set_level(level, verbose) != 0)
271  return -1;
272 
273  cs_subset_str_native_set(NeoMutt->sub, "debug_level", level, NULL);
274  return 0;
275 }
int mutt_log_set_file(const char *file, bool verbose)
Change the logging file.
Definition: mutt_logging.c:236
char * CurrentFile
The previous log file name.
Definition: mutt_logging.c:48
Container for Accounts, Notifications.
Definition: neomutt.h:36
int cs_subset_str_native_set(const struct ConfigSubset *sub, const char *name, intptr_t value, struct Buffer *err)
Natively set the value of a string config item.
Definition: subset.c:305
int log_file_set_level(enum LogLevel level, bool verbose)
Set the logging level.
Definition: logging.c:175
const char * cs_subset_path(const struct ConfigSubset *sub, const char *name)
Get a path config item by name.
Definition: helpers.c:194
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_log_start()

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 284 of file mutt_logging.c.

285 {
286  const short c_debug_level = cs_subset_number(NeoMutt->sub, "debug_level");
287  if (c_debug_level < 1)
288  return 0;
289 
290  if (log_file_running())
291  return 0;
292 
293  const char *const c_debug_file = cs_subset_path(NeoMutt->sub, "debug_file");
294  mutt_log_set_file(c_debug_file, false);
295 
296  /* This will trigger the file creation */
297  if (log_file_set_level(c_debug_level, true) < 0)
298  return -1;
299 
300  return 0;
301 }
int mutt_log_set_file(const char *file, bool verbose)
Change the logging file.
Definition: mutt_logging.c:236
short cs_subset_number(const struct ConfigSubset *sub, const char *name)
Get a number config item by name.
Definition: helpers.c:169
Container for Accounts, Notifications.
Definition: neomutt.h:36
int log_file_set_level(enum LogLevel level, bool verbose)
Set the logging level.
Definition: logging.c:175
bool log_file_running(void)
Is the log file running?
Definition: logging.c:230
const char * cs_subset_path(const struct ConfigSubset *sub, const char *name)
Get a path config item by name.
Definition: helpers.c:194
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ main_log_observer()

int main_log_observer ( struct NotifyCallback nc)

Notification that a Config Variable has changed - Implements observer_t.

Definition at line 321 of file mutt_logging.c.

322 {
323  if ((nc->event_type != NT_CONFIG) || !nc->event_data)
324  return -1;
325 
326  struct EventConfig *ev_c = nc->event_data;
327 
328  if (mutt_str_equal(ev_c->name, "debug_file"))
329  {
330  const char *const c_debug_file = cs_subset_path(NeoMutt->sub, "debug_file");
331  mutt_log_set_file(c_debug_file, true);
332  }
333  else if (mutt_str_equal(ev_c->name, "debug_level"))
334  {
335  const short c_debug_level = cs_subset_number(NeoMutt->sub, "debug_level");
336  mutt_log_set_level(c_debug_level, true);
337  }
338  else
339  {
340  return 0;
341  }
342 
343  mutt_debug(LL_DEBUG5, "log done\n");
344  return 0;
345 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:904
int mutt_log_set_file(const char *file, bool verbose)
Change the logging file.
Definition: mutt_logging.c:236
A config-change event.
Definition: subset.h:69
short cs_subset_number(const struct ConfigSubset *sub, const char *name)
Get a number config item by name.
Definition: helpers.c:169
Container for Accounts, Notifications.
Definition: neomutt.h:36
enum NotifyType event_type
Send: Event type, e.g. NT_ACCOUNT.
Definition: observer.h:42
int mutt_log_set_level(enum LogLevel level, bool verbose)
Change the logging level.
Definition: mutt_logging.c:262
const char * cs_subset_path(const struct ConfigSubset *sub, const char *name)
Get a path config item by name.
Definition: helpers.c:194
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
void * event_data
Data from notify_send()
Definition: observer.h:44
Config has changed, NotifyConfig, EventConfig.
Definition: notify_type.h:42
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
Log at debug level 5.
Definition: logging.h:44
const char * name
Name of config item that changed.
Definition: subset.h:72
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ LastError

uint64_t LastError = 0

Time of the last error message (in milliseconds since the Unix epoch)

Definition at line 46 of file mutt_logging.c.

◆ CurrentFile

char* CurrentFile = NULL

The previous log file name.

Definition at line 48 of file mutt_logging.c.

◆ NumOfLogs

const int NumOfLogs = 5

How many log files to rotate.

Definition at line 49 of file mutt_logging.c.