Changeset: 465cc1be670d for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=465cc1be670d
Modified Files:
        clients/mapiclient/tachograph.c
        monetdb5/mal/mal.c
        monetdb5/mal/mal.h
        monetdb5/mal/mal_listing.c
        monetdb5/mal/mal_listing.h
        monetdb5/mal/mal_profiler.c
        monetdb5/optimizer/Makefile.ag
        monetdb5/optimizer/opt_pipes.c
        monetdb5/optimizer/opt_prelude.c
        monetdb5/optimizer/opt_prelude.h
        monetdb5/optimizer/opt_support.c
        monetdb5/optimizer/opt_support.h
        monetdb5/optimizer/opt_wrapper.c
        monetdb5/optimizer/optimizer.mal
        tools/mserver/mserver5.c
Branch: profiler
Log Message:

JSON based profiling
First step into moving performance monitoring
to the (less humanreadable) JSON format structure.


diffs (truncated from 602 to 300 lines):

diff --git a/clients/mapiclient/tachograph.c b/clients/mapiclient/tachograph.c
--- a/clients/mapiclient/tachograph.c
+++ b/clients/mapiclient/tachograph.c
@@ -750,6 +750,7 @@ update(EventRecord *ev)
                fprintf(tachojson,"{\n");
                
fprintf(tachojson,"\"qid\":\"%s\",\n",currentfunction?currentfunction:"");
                fprintf(tachojson,"\"tag\":%d,\n",ev->tag);
+               fprintf(tachojson,"\"thread\":%d,\n",ev->thread);
                fprintf(tachojson,"\"pc\":%d,\n",ev->pc);
                fprintf(tachojson,"\"time\": "LLFMT",\n",ev->clkticks);
                fprintf(tachojson,"\"status\": \"done\",\n");
diff --git a/monetdb5/mal/mal.c b/monetdb5/mal/mal.c
--- a/monetdb5/mal/mal.c
+++ b/monetdb5/mal/mal.c
@@ -12,7 +12,7 @@
 
 char monet_cwd[PATHLENGTH] = { 0 };
 size_t monet_memory;
-char   monet_characteristics[PATHLENGTH];
+char   monetdb_characteristics[PATHLENGTH];
 int mal_trace;         /* enable profile events on console */
 #ifdef HAVE_HGE
 int have_hge;
diff --git a/monetdb5/mal/mal.h b/monetdb5/mal/mal.h
--- a/monetdb5/mal/mal.h
+++ b/monetdb5/mal/mal.h
@@ -48,7 +48,7 @@
 
 mal_export char     monet_cwd[PATHLENGTH];
 mal_export size_t      monet_memory;
-mal_export char        monet_characteristics[PATHLENGTH];
+mal_export char        monetdb_characteristics[PATHLENGTH];
 mal_export lng                 memorypool;      /* memory claimed by 
concurrent threads */
 mal_export int                 memoryclaims;    /* number of threads active 
with expensive operations */
 mal_export int         mal_trace;              /* enable profile events on 
console */
diff --git a/monetdb5/mal/mal_listing.c b/monetdb5/mal/mal_listing.c
--- a/monetdb5/mal/mal_listing.c
+++ b/monetdb5/mal/mal_listing.c
@@ -16,6 +16,7 @@
 #include "mal_utils.h"
 #include "mal_exception.h"
 #include "mal_listing.h"
+#include "mal_properties.h"
 
 /* 
  * Since MAL programs can be created on the fly by linked-in query
@@ -376,6 +377,115 @@ instruction2str(MalBlkPtr mb, MalStkPtr 
        return s;
 }
 
+/* the MAL beautifier is meant to simplify correlation of MAL variables and
+ * the columns in the underlying database.
+ * If the status is set, then we consider the instruction DONE and the result 
variables 
+ * should be shown as well.
+ */
+static str
+beautyTerm(MalBlkPtr mb, MalStkPtr stk, InstrPtr p, int idx)
+{
+       str s, nme;
+       BAT *b;
+       ValRecord *val;
+       //VarPtr v;
+       char *cv =0;
+       int varid = getArg(p,idx);
+
+       s= GDKmalloc(BUFSIZ);
+       *s = 0;
+
+       if( isVarConstant(mb,varid) ){
+               val =&getVarConstant(mb, varid);
+               VALformat(&cv, val);
+               snprintf(s,BUFSIZ,"%s",cv);
+               if(cv)
+                       GDKfree(cv);
+       } else {
+               val = &stk->stk[varid];
+               VALformat(&cv, val);
+               //v = varGetProp(mb, varid, PropertyIndex("schematablecolumn"));
+               nme = getVarName(mb, varid);
+               if ( isaBatType(getArgType(mb,p,idx))){
+                       b = BBPquickdesc(abs(stk->stk[varid].val.ival),TRUE);
+                       snprintf(s,BUFSIZ,"%s["BUNFMT"]",nme, b?BATcount(b):0);
+               } else
+                       snprintf(s,BUFSIZ,"%s",nme);
+               GDKfree(nme);
+       }
+       return s;
+}
+
+str
+instruction2beauty(MalBlkPtr mb, MalStkPtr stk,  InstrPtr p, int done)
+{
+       int i;
+       str base, s, t, nme;
+       size_t len=  (mb->stop < 1000? 1000: mb->stop) * 128 /* max realistic 
line length estimate */;
+
+       base = s = GDKmalloc(len);
+       if ( s == NULL)
+               return s;
+       *s =0;
+       t=s;
+       if (p->token == REMsymbol) 
+               return base;
+       // handle the result variables
+       if( done ){
+               for (i = 0; i < p->retc; i++)
+                       if (!getVarTmp(mb, getArg(p, i)) || isVarUsed(mb, 
getArg(p, i)) || isVarUDFtype(mb,getArg(p,i)))
+                               break;
+
+               if (i == p->retc) // no result arguments
+                       goto beauty_end;
+
+               /* display optional multi-assignment list */
+               if (p->retc > 1)
+                       *t++ = '(';
+
+               for (i = 0; i < p->retc; i++) {
+                       nme = beautyTerm(mb, stk, p,i);
+                       snprintf(t,(len-(t-base)), "%s", nme);
+                       GDKfree(nme);
+                       advance(t,base,len);
+                       if (i < p->retc - 1)
+                               *t++ = ',';
+               }
+               if (p->retc > 1)
+                       *t++ = ')';
+
+       }
+       beauty_end:
+       // handle the instruction mapping
+
+       advance(t,base,len);
+       nme = 0;
+       //nme = varGetPropStr(mb, getArg(p,0), PropertyIndex("beautyoperator"));
+       if( nme){
+               snprintf(t,  (len-(t-base)),"%s", nme);
+               GDKfree(nme);
+       } else 
+               snprintf(t,  (len-(t-base)),"%s.%s", getModuleId(p), 
getFunctionId(p));
+       advance(t,base,len);
+
+       // handle the arguments, constants should  be shown including their 
non-default type
+       /* display optional multi-assignment list */
+       *t++ = '(';
+       for (i = 0; i < p->retc; i++) {
+               nme = beautyTerm(mb, stk, p,i);
+               snprintf(t,(len-(t-base)), "%s", nme);
+               GDKfree(nme);
+               advance(t,base,len);
+               if (i < p->retc - 1)
+                       *t++ = ',';
+       }
+       *t++ = ')';
+
+       if (t >= s + len)
+               throw(MAL,"instruction2str:","instruction too long");
+       return s;
+}
+
 /* Remote execution of MAL calls for more type/property information to be 
exchanged */
 str
 mal2str(MalBlkPtr mb, int first, int last)
diff --git a/monetdb5/mal/mal_listing.h b/monetdb5/mal/mal_listing.h
--- a/monetdb5/mal/mal_listing.h
+++ b/monetdb5/mal/mal_listing.h
@@ -21,6 +21,7 @@ mal_export void printInstruction(stream 
 mal_export str instructionCall(MalBlkPtr mb, InstrPtr p, str s, str base, 
size_t len);
 mal_export void promptInstruction(stream *fd, MalBlkPtr mb, MalStkPtr stk, 
InstrPtr p, int flg);
 mal_export str instruction2str(MalBlkPtr mb, MalStkPtr stl, InstrPtr p, int 
hidden);
+mal_export str instruction2beauty(MalBlkPtr mb, MalStkPtr stl, InstrPtr p, int 
done);
 mal_export str mal2str(MalBlkPtr mb, int first, int last);
 mal_export void showMalBlkHistory(stream *out, MalBlkPtr mb);
 
diff --git a/monetdb5/mal/mal_profiler.c b/monetdb5/mal/mal_profiler.c
--- a/monetdb5/mal/mal_profiler.c
+++ b/monetdb5/mal/mal_profiler.c
@@ -25,10 +25,12 @@ stream *eventstream = 0;
 
 static int offlineProfiling = FALSE;
 static int cachedProfiling = FALSE;
+static int jsonrendering = TRUE;
 static str myname = 0;
 static oid user = 0;
 
 static void offlineProfilerEvent(MalBlkPtr mb, MalStkPtr stk, InstrPtr pc, int 
start, char *alter, char *msg);
+static void offlineProfilerEventJSON(MalBlkPtr mb, MalStkPtr stk, InstrPtr pc, 
int start, char *alter, char *msg);
 static void cachedProfilerEvent(MalBlkPtr mb, MalStkPtr stk, InstrPtr pc);
 static int initTrace(void);
 
@@ -56,6 +58,8 @@ offlineProfilerHeader(void)
 
        if (eventstream == NULL) 
                return ;
+       if (jsonrendering) 
+               return;
 
        lognew();
        logadd("# ");
@@ -106,7 +110,46 @@ static void logsend(char *logbuffer)
                error= mnstr_flush(eventstream);
                MT_lock_unset(&mal_profileLock, "logsend");
                if( showsystem)
-                       offlineProfilerEvent(0, 0, 0, 0, "system", 
monet_characteristics);
+                       offlineProfilerEvent(0, 0, 0, 0, "system", 
monetdb_characteristics);
+               if ( error) stopProfiler();
+       }
+}
+
+static void logsendJSON(char *logbuffer)
+{      int error=0;
+       char buf[BUFSIZ], *s;
+       size_t len, out;
+
+       if (eventstream) {
+               MT_lock_set(&mal_profileLock, "logsendJSON");
+               if( eventcounter == 0){
+                       snprintf(buf,BUFSIZ,"%s\n",monetdb_characteristics);
+                       len = strlen(buf);
+                       out = mnstr_write(eventstream, buf, 1, len);
+                       if( out != len){
+                               MT_lock_unset(&mal_profileLock, "logsendJSON");
+                               stopProfiler();
+                               return;
+                       }
+               }
+               eventcounter++;
+               snprintf(buf,BUFSIZ,"%d",eventcounter);
+               s = strchr(logbuffer,(int) ':');
+               if( s == NULL){
+                       MT_lock_unset(&mal_profileLock, "logsendJSON");
+                       return;
+               }
+       
+               strncpy(s+1, buf,strlen(buf));
+               len = strlen(logbuffer);
+               out= mnstr_write(eventstream, logbuffer, 1, len);
+               if( out != len){
+                       MT_lock_unset(&mal_profileLock, "logsendJSON");
+                       stopProfiler();
+                       return;
+               }
+               error= mnstr_flush(eventstream);
+               MT_lock_unset(&mal_profileLock, "logsendJSON");
                if ( error) stopProfiler();
        }
 }
@@ -126,8 +169,10 @@ profilerEvent(oid usr, MalBlkPtr mb, Mal
        if (pci == NULL) return;
        if (getModuleId(pci) == myname) // ignore profiler commands from 
monitoring
                return;
-       if (offlineProfiling)
+       if (offlineProfiling && !jsonrendering)
                offlineProfilerEvent(mb, stk, pci, start,0,0);
+       if (offlineProfiling && jsonrendering)
+               offlineProfilerEventJSON(mb, stk, pci, start,0,0);
        if (cachedProfiling && !start )
                cachedProfilerEvent(mb, stk, pci);
        if ( start && pci->pc ==0)
@@ -253,6 +298,158 @@ offlineProfilerEvent(MalBlkPtr mb, MalSt
        logadd("\t]\n"); // end marker
        logsend(logbuffer);
 }
+
+/* JSON rendering method of performance data. Using the table header as tag, 
breaking the complex fields. Example:
+ */
+void
+offlineProfilerEventJSON(MalBlkPtr mb, MalStkPtr stk, InstrPtr pci, int start, 
char *alter, char *msg)
+{
+       char logbuffer[LOGLEN], *logbase;
+       int loglen;
+       char ctm[26];
+       time_t clk;
+       struct timeval clock;
+       str stmt, c;
+       char *tbuf;
+       str stmtq;
+
+       if (eventstream == NULL)
+               return ;
+       if (jsonrendering == FALSE)
+               return ;
+
+       if( start) // show when instruction was started
+               clock = pci->clock;
+       else 
+               gettimeofday(&clock, NULL);
+       clk = clock.tv_sec;
+
+       /* make basic profile event tuple  */
+       lognew();
+       logadd("{ \"event\":         ,\n"); // fill in later with the event 
counter
+
+       /* without this cast, compilation on Windows fails with
+        * argument of type "long *" is incompatible with parameter of type 
"const time_t={__time64_t={__int64}} *"
+        */
+#ifdef HAVE_CTIME_R3
+       tbuf = ctime_r(&clk, ctm, sizeof(ctm));
+#else
+#ifdef HAVE_CTIME_R
+       tbuf = ctime_r(&clk, ctm);
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to