degesch: add logging to file
This commit is contained in:
parent
3503b76015
commit
94d495fbfa
115
degesch.c
115
degesch.c
@ -1018,6 +1018,8 @@ struct buffer
|
||||
unsigned unseen_messages_count; ///< # messages since last visited
|
||||
bool highlighted; ///< We've been highlighted
|
||||
|
||||
FILE *log_file; ///< Log file
|
||||
|
||||
// Origin information:
|
||||
|
||||
struct server *server; ///< Reference to server
|
||||
@ -1041,6 +1043,8 @@ buffer_destroy (struct buffer *self)
|
||||
input_buffer_destroy (self->input_data);
|
||||
LIST_FOR_EACH (struct buffer_line, iter, self->lines)
|
||||
buffer_line_destroy (iter);
|
||||
if (self->log_file)
|
||||
(void) fclose (self->log_file);
|
||||
if (self->user)
|
||||
user_unref (self->user);
|
||||
if (self->channel)
|
||||
@ -1550,6 +1554,10 @@ static struct config_schema g_config_behaviour[] =
|
||||
.comment = "Beep when highlighted or on a new invisible PM",
|
||||
.type = CONFIG_ITEM_BOOLEAN,
|
||||
.default_ = "on" },
|
||||
{ .name = "logging",
|
||||
.comment = "Log buffer contents to file",
|
||||
.type = CONFIG_ITEM_BOOLEAN,
|
||||
.default_ = "off" },
|
||||
{}
|
||||
};
|
||||
|
||||
@ -2482,6 +2490,20 @@ buffer_update_time (struct app_context *ctx, time_t now)
|
||||
// Else the buffer was too small, which is pretty weird
|
||||
}
|
||||
|
||||
static void
|
||||
buffer_line_flush (struct buffer_line *line, struct formatter *f, FILE *output)
|
||||
{
|
||||
int flags = line->flags;
|
||||
if (flags & BUFFER_LINE_INDENT) formatter_add (f, " ");
|
||||
if (flags & BUFFER_LINE_STATUS) formatter_add (f, " - ");
|
||||
if (flags & BUFFER_LINE_ERROR) formatter_add (f, "#a=!=#r ", ATTR_ERROR);
|
||||
|
||||
formatter_add_from (f, line->formatter);
|
||||
formatter_add (f, "\n");
|
||||
formatter_flush (f, output);
|
||||
formatter_free (f);
|
||||
}
|
||||
|
||||
static void
|
||||
buffer_line_display (struct app_context *ctx,
|
||||
struct buffer_line *line, bool is_external)
|
||||
@ -2494,12 +2516,13 @@ buffer_line_display (struct app_context *ctx,
|
||||
formatter_init (&f, ctx, NULL);
|
||||
|
||||
struct tm current;
|
||||
char buf[9];
|
||||
if (!localtime_r (&line->when, ¤t))
|
||||
print_error ("%s: %s", "localtime_r", strerror (errno));
|
||||
else if (!strftime (buf, sizeof buf, "%T", ¤t))
|
||||
print_error ("%s: %s", "strftime", "buffer too small");
|
||||
else
|
||||
formatter_add (&f, "#a#&s#r ", ATTR_TIMESTAMP,
|
||||
xstrdup_printf ("%02d:%02d:%02d",
|
||||
current.tm_hour, current.tm_min, current.tm_sec));
|
||||
formatter_add (&f, "#a#s#r ", ATTR_TIMESTAMP, buf);
|
||||
|
||||
// Ignore all formatting for messages coming from other buffers, that is
|
||||
// either from the global or server buffer. Instead print them in grey.
|
||||
@ -2509,26 +2532,33 @@ buffer_line_display (struct app_context *ctx,
|
||||
FORMATTER_ADD_ITEM (&f, IGNORE_ATTR, .attribute = 1);
|
||||
}
|
||||
|
||||
if (line->flags & BUFFER_LINE_INDENT)
|
||||
formatter_add (&f, " ");
|
||||
if (line->flags & BUFFER_LINE_STATUS)
|
||||
formatter_add (&f, " - ");
|
||||
if (line->flags & BUFFER_LINE_ERROR)
|
||||
formatter_add (&f, "#a=!=#r ", ATTR_ERROR);
|
||||
formatter_add_from (&f, line->formatter);
|
||||
|
||||
input_hide (&ctx->input);
|
||||
|
||||
// TODO: write the line to a log file; note that the global and server
|
||||
// buffers musn't collide with filenames
|
||||
|
||||
formatter_add (&f, "\n");
|
||||
formatter_flush (&f, stdout);
|
||||
formatter_free (&f);
|
||||
|
||||
buffer_line_flush (line, &f, stdout);
|
||||
input_show (&ctx->input);
|
||||
}
|
||||
|
||||
static void
|
||||
buffer_line_write_to_log (struct app_context *ctx,
|
||||
struct buffer_line *line, FILE *log_file)
|
||||
{
|
||||
if (line->flags & BUFFER_LINE_SKIP_FILE)
|
||||
return;
|
||||
|
||||
struct formatter f;
|
||||
formatter_init (&f, ctx, NULL);
|
||||
|
||||
struct tm current;
|
||||
char buf[20];
|
||||
if (!gmtime_r (&line->when, ¤t))
|
||||
print_error ("%s: %s", "gmtime_r", strerror (errno));
|
||||
else if (!strftime (buf, sizeof buf, "%F %T", ¤t))
|
||||
print_error ("%s: %s", "strftime", "buffer too small");
|
||||
else
|
||||
formatter_add (&f, "#s ", buf);
|
||||
|
||||
buffer_line_flush (line, &f, log_file);
|
||||
}
|
||||
|
||||
static void
|
||||
log_formatter (struct app_context *ctx,
|
||||
struct buffer *buffer, int flags, struct formatter *f)
|
||||
@ -2547,6 +2577,9 @@ log_formatter (struct app_context *ctx,
|
||||
LIST_APPEND_WITH_TAIL (buffer->lines, buffer->lines_tail, line);
|
||||
buffer->lines_count++;
|
||||
|
||||
if (buffer->log_file)
|
||||
buffer_line_write_to_log (ctx, line, buffer->log_file);
|
||||
|
||||
if (get_config_boolean (ctx->config.root, "behaviour.beep_on_highlight"))
|
||||
if ((flags & BUFFER_LINE_HIGHLIGHT)
|
||||
|| (buffer->type == BUFFER_PM && buffer != ctx->current_buffer))
|
||||
@ -2634,6 +2667,41 @@ log_full (struct app_context *ctx, struct server *s, struct buffer *buffer,
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
static void
|
||||
make_log_filename (const char *filename, struct str *output)
|
||||
{
|
||||
for (const char *p = filename; *p; p++)
|
||||
// XXX: anything more to replace?
|
||||
if (strchr ("/\\ ", *p))
|
||||
str_append_c (output, '_');
|
||||
else
|
||||
str_append_c (output, tolower_ascii (*p));
|
||||
}
|
||||
|
||||
static void
|
||||
buffer_open_log_file (struct app_context *ctx, struct buffer *buffer)
|
||||
{
|
||||
if (!get_config_boolean (ctx->config.root, "behaviour.logging"))
|
||||
return;
|
||||
|
||||
struct str path;
|
||||
str_init (&path);
|
||||
get_xdg_home_dir (&path, "XDG_DATA_HOME", ".local/share");
|
||||
str_append_printf (&path, "/%s/%s", PROGRAM_NAME, "logs");
|
||||
|
||||
(void) mkdir_with_parents (path.str, NULL);
|
||||
|
||||
// TODO: make sure global and server buffers don't collide with filenames
|
||||
str_append_c (&path, '/');
|
||||
make_log_filename (buffer->name, &path);
|
||||
str_append (&path, ".log");
|
||||
|
||||
if (!(buffer->log_file = fopen (path.str, "ab")))
|
||||
log_global_error (ctx, "Couldn't open log file `#s': #s",
|
||||
path.str, strerror (errno));
|
||||
str_free (&path);
|
||||
}
|
||||
|
||||
static struct buffer *
|
||||
buffer_by_name (struct app_context *ctx, const char *name)
|
||||
{
|
||||
@ -2648,6 +2716,8 @@ buffer_add (struct app_context *ctx, struct buffer *buffer)
|
||||
str_map_set (&ctx->buffers_by_name, buffer->name, buffer);
|
||||
LIST_APPEND_WITH_TAIL (ctx->buffers, ctx->buffers_tail, buffer);
|
||||
|
||||
buffer_open_log_file (ctx, buffer);
|
||||
|
||||
// In theory this can't cause changes in the prompt
|
||||
refresh_prompt (ctx);
|
||||
}
|
||||
@ -2776,6 +2846,13 @@ buffer_rename (struct app_context *ctx,
|
||||
str_map_set (&ctx->buffers_by_name, buffer->name, NULL);
|
||||
str_map_set (&ctx->buffers_by_name, new_name, buffer);
|
||||
|
||||
if (buffer->log_file)
|
||||
{
|
||||
(void) fclose (buffer->log_file);
|
||||
buffer->log_file = NULL;
|
||||
}
|
||||
buffer_open_log_file (ctx, buffer);
|
||||
|
||||
free (buffer->name);
|
||||
buffer->name = xstrdup (new_name);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user