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

Reply via email to