Changeset: 64e70976e111 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=64e70976e111
Modified Files:
        gdk/gdk_tracer.c
Branch: gdk_tracer
Log Message:

Exception handling in GDKtracer & removed 2nd buffer


diffs (291 lines):

diff --git a/gdk/gdk_tracer.c b/gdk/gdk_tracer.c
--- a/gdk/gdk_tracer.c
+++ b/gdk/gdk_tracer.c
@@ -41,16 +41,14 @@
 #endif
 
 static gdk_tracer tracer = { .allocated_size = 0, .id = 0 };
-static gdk_tracer secondary_tracer = { .allocated_size = 0, .id = 1 };
 static MT_Lock lock = MT_LOCK_INITIALIZER("GDKtracer");
-static ATOMIC_TYPE SELECTED_tracer_ID = 0;
 
 static FILE *output_file;
+static bool USE_STREAM = true;
+
 static ATOMIC_TYPE CUR_ADAPTER = DEFAULT_ADAPTER;
 
 static LOG_LEVEL CUR_FLUSH_LEVEL = DEFAULT_FLUSH_LEVEL;
-// LOG_LEVEL LVL_PER_COMPONENT[COMPONENTS_COUNT] = {[0 ... COMPONENTS_COUNT-1] 
= DEFAULT_LOG_LEVEL};
-
 static bool GDK_TRACER_STOP = false;
 
 static const char *LAYER_STR[] = {
@@ -66,34 +64,23 @@ LOG_LEVEL LVL_PER_COMPONENT[] = {
 };
 
 
-// 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)
+static gdk_return
+_GDKtracer_init_basic_adptr(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");
+    sprintf(file_name, "%s%c%s%c%s%s", GDKgetenv("gdk_dbpath"), DIR_SEP, 
FILE_NAME, NAME_SEP, GDKtracer_get_timestamp("%Y-%m-%dT%H:%M:%S"), ".log");
 
     output_file = fopen(file_name, "w");
 
-    _GDKtracer_file_is_open(output_file);
+    if(!output_file)
+    {
+        GDK_TRACER_REPORT_EXCEPTION("Failed to initialize BASIC adapter. Could 
not open file: %s\n", file_name);
+        return GDK_FAIL;
+    }
+
+    return GDK_SUCCEED;
 }
 
 
@@ -165,9 +152,11 @@ static int
     if(fmt[fmt_len - 1] != NEW_LINE)
     {
         tmp = malloc(sizeof(char) * (fmt_len + 2));
-        if(tmp == NULL)
+        if(!tmp)
         {
-            fprintf(stderr, "Memory allocation failed\n");
+            // Let GDKtracer_log to know about the failure
+            GDK_TRACER_REPORT_EXCEPTION("Memory allocation failed\n");
+            return -1;
         }
         else
         {
@@ -189,7 +178,9 @@ static int
     if(tmp)
         free(tmp);
 
-    _GDKtracer_log_output_error(bytes_written);
+    // Let GDKtracer_log to know about the failure
+    if(bytes_written < 0)
+        return -1;
 
     // vsnprintf returned value -> does not include the null terminating 
character
     return bytes_written++;
@@ -269,8 +260,7 @@ GDKtracer_get_timestamp(char* fmt)
 gdk_return
 GDKtracer_init(void)
 {
-    _GDKtracer_create_file();
-    return GDK_SUCCEED;
+    return _GDKtracer_init_basic_adptr();
 }
 
 
@@ -407,60 +397,45 @@ GDKtracer_log(LOG_LEVEL level, char *fmt
 {      
     gdk_tracer *fill_tracer;
     int bytes_written = 0;
-    int GDK_result;
 
     MT_lock_set(&lock);
     {
-        if((int) ATOMIC_GET(&SELECTED_tracer_ID) == tracer.id)
-            fill_tracer = &tracer;
-        else
-            fill_tracer = &secondary_tracer;
+        fill_tracer = &tracer;
 
         va_list va;
         va_start(va, fmt);
         bytes_written = _GDKtracer_fill_tracer(fill_tracer, fmt, va);
         va_end(va);
 
-        // The message fits the buffer OR the buffer is empty (we don't care 
if it fits - just cut it off)
-        if(bytes_written < (BUFFER_SIZE - fill_tracer->allocated_size) || 
-            fill_tracer->allocated_size == 0)
+        if(bytes_written < 0)
         {
-            fill_tracer->allocated_size += bytes_written;
+            GDK_TRACER_REPORT_EXCEPTION("Cannot write data to the buffer, 
discarding this entry\n");
+            /* CHECK */
+            // Maybe here add return GDK_FAIL?
         }
         else
         {
-            /* CHECK */
-            // Create thread for that
-            // Flush the full tracer on a separate thread
-            GDKtracer_flush_buffer();
-            //         MT_Id tid;
-            //         if(MT_create_thread(&tid, (void(*) (void*)) 
GDKtracer_flush_buffer, NULL, MT_THR_JOINABLE, "GDKtracerFlush") < 0)
-            //             fprintf(stderr, "MT_create_thread FAILED!\n");
-            //             // return GDK_FAIL;
-            //         GDK_result = MT_join_thread(tid);
-            //         if(GDK_result == GDK_FAIL)
-            //             fprintf(stderr, "MT_join_thread FAILED!\n");
-            //             // return GDK_FAIL;
+            // The message fits the buffer OR the buffer is empty but the 
message does not fit (we cut it off)
+            if(bytes_written < (BUFFER_SIZE - fill_tracer->allocated_size) || 
+                fill_tracer->allocated_size == 0)
+            {
+                fill_tracer->allocated_size += bytes_written;
+            }
+            else
+            {
+                GDKtracer_flush_buffer();
 
-            // Switch tracer
-            if((int) ATOMIC_GET(&SELECTED_tracer_ID) == tracer.id)
-                fill_tracer = &secondary_tracer;
-            else
-                fill_tracer = &tracer;
-
-            // Set the new selected tracer 
-            ATOMIC_SET(&SELECTED_tracer_ID, fill_tracer->id);  
+                // Write to the new tracer
+                va_list va;
+                va_start(va, fmt);
+                bytes_written = _GDKtracer_fill_tracer(fill_tracer, fmt, va);
+                va_end(va);
 
-            // Write to the new tracer
-            va_list va;
-            va_start(va, fmt);
-            bytes_written = _GDKtracer_fill_tracer(fill_tracer, fmt, va);
-            va_end(va);
-
-            // The second buffer will always be empty at start
-            // So if the message does not fit we cut it off
-            // message might be > BUFFER_SIZE
-            fill_tracer->allocated_size += bytes_written;      
+                // The second buffer will always be empty at start
+                // So if the message does not fit we cut it off
+                // message might be > BUFFER_SIZE
+                fill_tracer->allocated_size += bytes_written;      
+            }
         }
     }
     MT_lock_unset(&lock);
@@ -475,27 +450,18 @@ GDKtracer_log(LOG_LEVEL level, char *fmt
        level == M_CRITICAL      || 
        level == M_ERROR)
     {
-        GDK_result = GDKtracer_flush_buffer();
-        if(GDK_result == GDK_FAIL)
-            return GDK_FAIL;
+        GDKtracer_flush_buffer();
     }
 
     return GDK_SUCCEED;
 }
 
 
-/* CHECK */
-// TODO: This can be called independently from GDKtracer_log
-// Hence we need a lock when flushing the buffer on demand
 gdk_return
 GDKtracer_flush_buffer(void)
 {
     // Select a tracer
-    gdk_tracer *fl_tracer;
-    if((int) ATOMIC_GET(&SELECTED_tracer_ID) == tracer.id)
-        fl_tracer = &tracer;
-    else
-        fl_tracer = &secondary_tracer;
+    gdk_tracer *fl_tracer = &tracer;
 
     // No reason to flush a buffer with no content 
     if(fl_tracer->allocated_size == 0)
@@ -503,25 +469,42 @@ GDKtracer_flush_buffer(void)
 
     if(ATOMIC_GET(&CUR_ADAPTER) == BASIC)
     {
-        // Check if file is open - if not send the output to stderr. There are 
cases that 
+        // Check if file is open - if not send the output to GDKstdout. There 
are cases that 
         // this is needed - e.g: on startup of mserver5 GDKmalloc is called 
before GDKinit. 
         // In GDKinit GDKtracer is getting initialized (open_file and 
initialize log level 
         // per component). Since the file is not open yet and there is an 
assert, we need 
-        // to do something - and as a backup plan we send the logs to stderr.
-        // _GDKtracer_file_is_open(output_file);
-        if(!output_file)
-            output_file = stderr;
+        // to do something - and as a backup plan we send the logs to 
GDKstdout.
+        if(output_file)
+        {
+            /* CHECK */
+            // This should be working!
+            // size_t w = fwrite(&fl_tracer->buffer, 
fl_tracer->allocated_size, 1, output_file);
 
-        fwrite(&fl_tracer->buffer, fl_tracer->allocated_size, 1, output_file);
-        fflush(stderr);
+            // fwrite failed for whatever reason 
+            // (e.g: disk is full) fallback to stream
+            // if(w == (size_t) fl_tracer->allocated_size)
+            // {   
+            //     USE_STREAM = false;
+            //     fflush(output_file);
+            // }
+
+            fwrite(&fl_tracer->buffer, fl_tracer->allocated_size, 1, 
output_file);
+            fflush(output_file);
+            USE_STREAM = false;
+        }
+
+        // Write buffer to a stream
+        if(USE_STREAM)
+            mnstr_printf(GDKstdout, "%s", fl_tracer->buffer);
             
+
         // Reset buffer
         memset(fl_tracer->buffer, 0, BUFFER_SIZE);
         fl_tracer->allocated_size = 0;
     }
     else
     {
-        fprintf(stderr, "Using adapter: %s", ADAPTER_STR[(int) 
ATOMIC_GET(&CUR_ADAPTER)]);
+        mnstr_printf(GDKstdout, "Using adapter: %s", ADAPTER_STR[(int) 
ATOMIC_GET(&CUR_ADAPTER)]);
     }
 
     // The file is kept open no matter the adapter
@@ -550,18 +533,16 @@ GDKtracer_show_info(void)
             max_width = comp_width;
     }
 
-    fprintf(stderr, "# LOG level per component\n");
+    mnstr_printf(GDKstdout, "# LOG level per component\n");
     for(i = 0; i < COMPONENTS_COUNT; i++)
     {
         space = (int) (max_width - strlen(COMPONENT_STR[i]) + 30);
-        fprintf(stderr, "# %s %*s\n", COMPONENT_STR[i], space, 
LEVEL_STR[LVL_PER_COMPONENT[i]]);
+        mnstr_printf(GDKstdout, "# %s %*s\n", COMPONENT_STR[i], space, 
LEVEL_STR[LVL_PER_COMPONENT[i]]);
     }
 
-    fprintf(stderr, "# You can use one of the following layers to massively 
set the LOG level\n");
+    mnstr_printf(GDKstdout, "# You can use one of the following layers to 
massively set the LOG level\n");
     for(i = 0; i < LAYERS_COUNT; i++)
     {
-        fprintf(stderr, "# %s\n", LAYER_STR[i]);
+        mnstr_printf(GDKstdout, "# %s\n", LAYER_STR[i]);
     }
-
-    return GDK_SUCCEED;
 }
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to