Changeset: a3aecebd84ae for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=a3aecebd84ae Added Files: gdk/gdk_tracer.c gdk/gdk_tracer.h Modified Files: gdk/gdk_utils.c tools/mserver/mserver5.c Branch: gdk_tracer Log Message:
Replaced gdk_utils & mserver and added gdk_tracer diffs (truncated from 999 to 300 lines): diff --git a/gdk/gdk_tracer.c b/gdk/gdk_tracer.c new file mode 100644 --- /dev/null +++ b/gdk/gdk_tracer.c @@ -0,0 +1,532 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V. + * + * The tracer is the general logging system for the MonetDB stack. + * It is modelled after well-known logging schems, eg. Python + * + * Internally, the logger uses a dual buffer to capture log messages + * before they are written to a file. This way we avoid serial execution. + * + * The logger files come in two as well, where we switch them + * once the logger is full. + * The logger file format is "tracer_YY-MM-DDTHH:MM:SS_number.log" + * An option to consider is we need a rotating scheme over 2 files only, + * Moreover, old log files might be sent in the background to long term storage as well. + */ + +#include <assert.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> + +#include "monetdb_config.h" +#include "gdk.h" +#include "gdk_tracer.h" + + +static gdk_tracer tracer = { .allocated_size = 0, .id = 0, .lock = MT_LOCK_INITIALIZER("GDKtracerL") }; +static gdk_tracer secondary_tracer = { .allocated_size = 0, .id = 1, .lock = MT_LOCK_INITIALIZER("GDKtracerL2") }; +static ATOMIC_TYPE SELECTED_tracer_ID = 0; + +static FILE *output_file; +static ATOMIC_TYPE CUR_ADAPTER = DEFAULT_ADAPTER; + +static LOG_LEVEL CUR_FLUSH_LEVEL = DEFAULT_FLUSH_LEVEL; +LOG_LEVEL LVL_PER_COMPONENT[COMPONENTS_COUNT]; +static bool GDK_TRACER_STOP = false; + + +// Output error from snprintf of vsnprintf +static void +_GDKtracer_log_output_error(int bytes_written) +{ + assert(bytes_written >= 0); +} + + +static void +_GDKtracer_file_is_open(FILE *file) +{ + assert(file); +} + + +// Prepares a file in order to write the contents of the buffer when necessary +static void +_GDKtracer_create_file(void) +{ + char id[INT_MAX_LEN]; + snprintf(id, INT_MAX_LEN, "%d", 1); + + char file_name[FILENAME_MAX]; + sprintf(file_name, "%s%c%s%c%s%c%s%s", GDKgetenv("gdk_dbpath"), DIR_SEP, FILE_NAME, NAME_SEP, GDKtracer_get_timestamp("%Y-%m-%dT%H:%M:%S"), NAME_SEP, id, ".log"); + + output_file = fopen(file_name, "w"); + + _GDKtracer_file_is_open(output_file); +} + + +static void +_GDKtracer_init_components(void) +{ + for(int i = 0; i < COMPONENTS_COUNT; i++) + { + LVL_PER_COMPONENT[i] = DEFAULT_LOG_LEVEL; + } +} + + +static bool +_GDKtracer_adapter_exists(int *adapter) +{ + if(*adapter == ADAPTERS_COUNT) + return false; + + if(*adapter >= 0 && *adapter < ADAPTERS_COUNT) + return true; + + return false; +} + + +static bool +_GDKtracer_level_exists(int *level) +{ + if(*level == LOG_LEVELS_COUNT) + return false; + + if(*level >= 0 && *level < LOG_LEVELS_COUNT) + return true; + + return false; +} + + +static bool +_GDKtracer_layer_exists(int *layer) +{ + if(*layer == LAYERS_COUNT) + return false; + + if(*layer >= 0 && *layer < LAYERS_COUNT) + return true; + + return false; +} + + +static bool +_GDKtracer_component_exists(int *comp) +{ + if(*comp == COMPONENTS_COUNT) + return false; + + if(*comp >= 0 && *comp < COMPONENTS_COUNT) + return true; + + return false; +} + + +// Candidate for 'gnu_printf' format attribute [-Werror=suggest-attribute=format] +static int +_GDKtracer_fill_tracer(gdk_tracer *sel_tracer, char *fmt, va_list va) __attribute__ ((format (printf, 2, 0))); + +static int +_GDKtracer_fill_tracer(gdk_tracer *sel_tracer, char *fmt, va_list va) +{ + char *tmp = NULL; + const char* msg = NULL; + size_t fmt_len = strlen(fmt); + int bytes_written = 0; + + // Add \n if it doesn't exist + if(fmt[fmt_len - 1] != NEW_LINE) + { + tmp = GDKmalloc(sizeof(char) * (fmt_len + 2)); + strcpy(tmp, fmt); + tmp[fmt_len] = NEW_LINE; + tmp[fmt_len + 1] = NULL_CHAR; + msg = tmp; + } + else + { + msg = fmt; + } + + if(msg) + { + // vsnprintf(char *str, size_t count, ...) -> including null terminating character + bytes_written = vsnprintf(sel_tracer->buffer + sel_tracer->allocated_size, BUFFER_SIZE - sel_tracer->allocated_size, msg, va); + + if(tmp) + GDKfree(tmp); + } + + _GDKtracer_log_output_error(bytes_written); + + // vsnprintf returned value -> does not include the null terminating character + return bytes_written++; +} + + +static gdk_return +_GDKtracer_layer_level_helper(int *layer, int *level) +{ + char *tmp = NULL; + char *tok = NULL; + for(int i = 0; i < COMPONENTS_COUNT; i++) + { + if(*layer == MDB_ALL) + { + if(LVL_PER_COMPONENT[i] != *level) + LVL_PER_COMPONENT[i] = *level; + } + else + { + tmp = strdup(COMPONENT_STR[i]); + if(!tmp) + return GDK_FAIL; + + tok = strtok(tmp, "_"); + if(!tok) + return GDK_FAIL; + + switch(*layer) + { + case SQL_ALL: + if(strcmp(tok, "SQL") == 0) + if(LVL_PER_COMPONENT[i] != *level) + LVL_PER_COMPONENT[i] = *level; + break; + case MAL_ALL: + if(strcmp(tok, "MAL") == 0) + if(LVL_PER_COMPONENT[i] != *level) + LVL_PER_COMPONENT[i] = *level; + break; + case GDK_ALL: + if(strcmp(tok, "GDK") == 0) + if(LVL_PER_COMPONENT[i] != *level) + LVL_PER_COMPONENT[i] = *level; + break; + default: + break; + } + } + } + + return GDK_SUCCEED; +} + + + +/** + * + * API CALLS + * + */ +char* +GDKtracer_get_timestamp(char* fmt) +{ + static char datetime[20]; + time_t now = time(NULL); + struct tm *tmp = localtime(&now); + strftime(datetime, sizeof(datetime), fmt, tmp); + return datetime; +} + + +gdk_return +GDKtracer_init(void) +{ + _GDKtracer_init_components(); + _GDKtracer_create_file(); + return GDK_SUCCEED; +} + + +gdk_return +GDKtracer_stop(void) +{ + GDK_TRACER_STOP = true; + return GDKtracer_flush_buffer(); +} + + +gdk_return +GDKtracer_set_component_level(int *comp, int *level) +{ + if(LVL_PER_COMPONENT[*comp] == *level) + return GDK_SUCCEED; + + if(!_GDKtracer_component_exists(comp)) + return GDK_FAIL; + + if(!_GDKtracer_level_exists(level)) + return GDK_FAIL; + + LVL_PER_COMPONENT[*comp] = *level; + return GDK_SUCCEED; +} + + +gdk_return +GDKtracer_reset_component_level(int *comp) +{ + if(LVL_PER_COMPONENT[*comp] == DEFAULT_LOG_LEVEL) + return GDK_SUCCEED; + + if(!_GDKtracer_component_exists(comp)) + return GDK_FAIL; + + LVL_PER_COMPONENT[*comp] = DEFAULT_LOG_LEVEL; + return GDK_SUCCEED; +} + + +gdk_return +GDKtracer_set_layer_level(int *layer, int *level) _______________________________________________ checkin-list mailing list [email protected] https://www.monetdb.org/mailman/listinfo/checkin-list
