Skip to content

Commit

Permalink
Merge pull request #35 from mk-fg/add_timestamp_prefix_option
Browse files Browse the repository at this point in the history
feat: add -T/--timestamps (env LOGPROXY_TIMESTAMPS) option to prepend strftime to each line
  • Loading branch information
thebaptiste authored Feb 8, 2024
2 parents 072dc69 + b1a370c commit 262d47a
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 7 deletions.
8 changes: 4 additions & 4 deletions src/log_proxy.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ static void every_second() {
// another program rotated our log file
// => let's reinit the output channel
destroy_output_channel();
init_output_channel(log_file, use_locks, TRUE, chmod_str, chown_str, chgrp_str);
init_output_channel(log_file, use_locks, TRUE, chmod_str, chown_str, chgrp_str, timestamp_prefix);
unlock_control_file(fd);
return;
}
Expand All @@ -141,7 +141,7 @@ static void every_second() {
}
if (rotate_res == TRUE) {
destroy_output_channel();
init_output_channel(log_file, use_locks, TRUE, chmod_str, chown_str, chgrp_str);
init_output_channel(log_file, use_locks, TRUE, chmod_str, chown_str, chgrp_str, timestamp_prefix);
}
}
unlock_control_file(fd);
Expand Down Expand Up @@ -202,7 +202,7 @@ void init_or_reinit_output_channel(const gchar *lg_file, gboolean us_locks) {
exit(2);
}
destroy_output_channel();
init_output_channel(lg_file, us_locks, FALSE, chmod_str, chown_str, chgrp_str);
init_output_channel(lg_file, us_locks, FALSE, chmod_str, chown_str, chgrp_str, timestamp_prefix);
unlock_control_file(lock_fd);
}

Expand All @@ -212,7 +212,7 @@ int main(int argc, char *argv[])
setlocale(LC_ALL, "");
context = g_option_context_new("LOGFILE - log proxy");
g_option_context_add_main_entries(context, entries, NULL);
gchar *description = "Optional environment variables to override defaults: \n LOGPROXY_ROTATION_SIZE\n LOGPROXY_ROTATION_TIME\n LOGPROXY_ROTATION_SUFFIX\n LOGPROXY_LOG_DIRECTORY\n LOGPROXY_ROTATED_FILES\n\nExample for rotation-size option:\n- If log_proxy is run with the option --rotation-size on the command line, rotation-size will take the provided value\n- If the option --rotation-size is not provided on command line :\n - If the environment variable LOGPROXY_ROTATION_SIZE is set, rotation-size will take this value\n - If the environment variable LOGPROXY_ROTATION_SIZE is not set, rotation-size will take the default value 104857600\n";
gchar *description = "Optional environment variables to override defaults: \n LOGPROXY_ROTATION_SIZE\n LOGPROXY_ROTATION_TIME\n LOGPROXY_ROTATION_SUFFIX\n LOGPROXY_LOG_DIRECTORY\n LOGPROXY_ROTATED_FILES\n LOGPROXY_TIMESTAMPS\n\nExample for rotation-size option:\n- If log_proxy is run with the option --rotation-size on the command line, rotation-size will take the provided value\n- If the option --rotation-size is not provided on command line :\n - If the environment variable LOGPROXY_ROTATION_SIZE is set, rotation-size will take this value\n - If the environment variable LOGPROXY_ROTATION_SIZE is not set, rotation-size will take the default value 104857600\n";
g_option_context_set_description(context, description);
if (!g_option_context_parse(context, &argc, &argv, NULL)) {
g_print("%s", g_option_context_get_help(context, TRUE, NULL));
Expand Down
2 changes: 1 addition & 1 deletion src/log_proxy_wrapper.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ void spawn_logproxy_async(const gchar *fifo_path, const gchar *log_path) {
if (use_locks) {
use_locks_str = "--use-locks";
}
gchar *cli = g_strdup_printf("log_proxy -s %li -t %li -S \"%s\" -d \"%s\" -n %i %s -r -f \"%s\" \"%s\"", rotation_size, rotation_time, rotation_suffix, log_directory, rotated_files, use_locks_str, fifo_path, log_path);
gchar *cli = g_strdup_printf("log_proxy -s %li -t %li -S \"%s\" -d \"%s\" -T \"%s\" -n %i %s -r -f \"%s\" \"%s\"", rotation_size, rotation_time, rotation_suffix, log_directory, timestamp_prefix, rotated_files, use_locks_str, fifo_path, log_path);
gboolean spawn_res = g_spawn_command_line_async(cli, NULL);
if (spawn_res == FALSE) {
g_critical("can't spawn %s => exit", cli);
Expand Down
12 changes: 12 additions & 0 deletions src/options.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ static gchar *log_file = NULL;
static glong rotation_size = -1;
static glong rotation_time = -1;
static gchar *rotation_suffix = NULL;
static gchar *timestamp_prefix = NULL;
static gchar *log_directory = NULL;
static gchar *chmod_str = NULL;
static gchar *chown_str = NULL;
Expand Down Expand Up @@ -70,6 +71,16 @@ void set_default_values_from_env()
}
}

if ( timestamp_prefix == NULL ) {
env_val = g_getenv("LOGPROXY_TIMESTAMPS");
if ( env_val != NULL ) {
timestamp_prefix = (gchar *)env_val;
}
}
if ( timestamp_prefix != NULL && strlen(timestamp_prefix) == 0 ) {
timestamp_prefix = NULL;
}

if ( log_directory == NULL ) {
env_val = g_getenv("LOGPROXY_LOG_DIRECTORY");
if ( env_val != NULL ) {
Expand All @@ -94,6 +105,7 @@ static GOptionEntry entries[] = {
{ "rotation-suffix", 'S', 0, G_OPTION_ARG_STRING, &rotation_suffix, "strftime based suffix to append to rotated log files (default: content of environment variable LOGPROXY_ROTATION_SUFFIX or .%%Y%%m%%d%%H%%M%%S)", NULL },
{ "log-directory", 'd', 0, G_OPTION_ARG_STRING, &log_directory, "directory to store log files (default: content of environment variable LOGPROXY_LOG_DIRECTORY or current directory), directory is created if missing", NULL },
{ "rotated-files", 'n', 0, G_OPTION_ARG_INT, &rotated_files, "maximum number of rotated files to keep including main one (0 => no cleaning, default: content of environment variable LOGPROXY_ROTATED_FILES or 5)", NULL },
{ "timestamps", 'T', 0, G_OPTION_ARG_STRING, &timestamp_prefix, "strftime prefix to prepend to every output line (default: content of environment variable LOGPROXY_TIMESTAMPS or none)", NULL },
{ "chmod", 'c', 0, G_OPTION_ARG_STRING, &chmod_str, "if set, chmod the logfile to this value, '0700' for example (default: content of environment variable LOGPROXY_CHMOD or NULL)", NULL },
{ "chown", 'o', 0, G_OPTION_ARG_STRING, &chown_str, "if set, try (if you don't have sufficient privileges, it will fail silently) to change the owner of the logfile to the given user value", NULL },
{ "chgrp", 'g', 0, G_OPTION_ARG_STRING, &chgrp_str, "if set, try (if you don't have sufficient privileges, it will fail silently) to change the group of the logfile to the given group value", NULL },
Expand Down
18 changes: 17 additions & 1 deletion src/out.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ static GIOChannel *_out_channel = NULL;
static gboolean _use_locks = FALSE;
static gchar *_log_file = NULL;
static glong _log_file_initial_timestamp = 0;
static gchar *_timestamp_prefix = NULL;

glong get_output_channel_age() {
g_assert(_log_file_initial_timestamp > 0);
Expand All @@ -29,8 +30,9 @@ void destroy_output_channel() {
g_free(_log_file);
}

void init_output_channel(const gchar *log_file, gboolean use_locks, gboolean force_control_file, const gchar *chmod_str, const gchar *chown_str, const gchar *chgrp_str) {
void init_output_channel(const gchar *log_file, gboolean use_locks, gboolean force_control_file, const gchar *chmod_str, const gchar *chown_str, const gchar *chgrp_str, const gchar *timestamp_prefix) {
_log_file = g_strdup(log_file);
_timestamp_prefix = g_strdup(timestamp_prefix);
_use_locks = use_locks;
create_empty(_log_file);
_log_file_initial_timestamp = -1;
Expand Down Expand Up @@ -91,13 +93,27 @@ gboolean write_output_channel(GString *buffer) {
GIOStatus write_status;
GError *error = NULL;
gsize written;
gsize written_timestamp = 0;
while (TRUE) {
if (_use_locks) {
int res = flock(g_io_channel_unix_get_fd(_out_channel), LOCK_EX);
if (res < 0) {
continue;
}
}

if ( _timestamp_prefix != NULL && written_timestamp == 0 ) {
gchar *timestamp = compute_timestamp_prefix(_timestamp_prefix);
if ( timestamp != NULL ) {
write_status = g_io_channel_write_chars(_out_channel, timestamp,
strlen(timestamp), &written_timestamp, &error);
g_free(timestamp);
if (write_status == G_IO_STATUS_AGAIN) {
continue;
}
}
}

write_status = g_io_channel_write_chars(_out_channel, buffer->str,
buffer->len, &written, &error);
if (_use_locks) {
Expand Down
2 changes: 1 addition & 1 deletion src/out.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

#include <glib.h>

void init_output_channel(const gchar *log_file, gboolean use_locks, gboolean force_control_file, const gchar *chmod_str, const gchar *chown_str, const gchar *chgrp_str);
void init_output_channel(const gchar *log_file, gboolean use_locks, gboolean force_control_file, const gchar *chmod_str, const gchar *chown_str, const gchar *chgrp_str, const gchar *timestamp_prefix);
void destroy_output_channel();
gboolean write_output_channel(GString *buffer);
glong get_output_channel_age();
Expand Down
20 changes: 20 additions & 0 deletions src/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,26 @@ gchar *compute_strftime_suffix(const gchar *str, const gchar *strftime_suffix) {
return g_strdup_printf("%s%s", str, outstr);
}

/**
* Format current timestamp prefix to prepend to a log line.
*
* @param strftime_prefix format with strftime placeholders to expand with current time.
* @return newly allocated string (free it with g_free) with the current timestamp prefix.
*/
gchar *compute_timestamp_prefix(const gchar *strftime_prefix) {
time_t t;
struct tm *tmp;
t = time(NULL);
tmp = localtime(&t);
g_assert(tmp != NULL);
char outstr[100];
if (strftime(outstr, sizeof(outstr), strftime_prefix, tmp) == 0) {
g_critical("problem with strftime on %s", strftime_prefix);
return NULL;
}
return g_strdup(outstr);
}

/**
* Compute absolute file path from directory path and file name
*
Expand Down
1 change: 1 addition & 0 deletions src/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
glong get_file_size(const gchar *file_path);
glong get_current_timestamp();
gchar *compute_strftime_suffix(const gchar *str, const gchar *strftime_suffix);
gchar *compute_timestamp_prefix(const gchar *strftime_prefix);
gchar *get_unique_hexa_identifier();
glong get_file_inode(const gchar *file_path);
glong get_fd_inode(int fd);
Expand Down

0 comments on commit 262d47a

Please sign in to comment.