21baf6b09432d246060dc20af82ac367197d4121
braney
  Tue Jul 29 19:19:38 2014 -0700
output the list of visible tracks to error_log #13626
diff --git src/hg/hgTracks/hgTracks.c src/hg/hgTracks/hgTracks.c
index ae2379c..e004397 100644
--- src/hg/hgTracks/hgTracks.c
+++ src/hg/hgTracks/hgTracks.c
@@ -1902,30 +1902,77 @@
 
 	    /* create list of codons in the specified coding frame */
 	    sfList = baseColorCodonsFromDna(refFrame, winStart, winEnd,
                                             extraSeq, complementRulerBases);
 	    /* draw the codons in the list, with alternating colors */
 	    baseColorDrawRulerCodons(hvg, sfList, scale, insideX, y,
                                      codonHeight, font, winStart, MAXPIXELS,
                                      zoomedToCodonLevel);
 	    }
 	}
     }
 hvGfxUnclip(hvg);
 return y;
 }
 
+static void logTrackList(struct dyString *dy, struct track *trackList)
+/* add visibile tracks to dyString, recursively called */
+{
+if (trackList == NULL)
+    return;
+
+struct track *track;
+for (track = trackList; track != NULL; track = track->next)
+    {
+    int vis = track->limitedVisSet ? track->limitedVis : track->visibility;
+    if (vis)
+	{
+	logTrackList(dy, track->subtracks);
+	if (dy->stringSize)
+	    dyStringAppendC(dy, ',');
+	dyStringPrintf(dy,"%s:%d", track->track, vis);
+	}
+    }
+}
+
+static void logTrackVisibilities (char *hgsid, struct track *trackList)
+/* log visibile tracks and hgsid */
+{
+struct dyString *dy = newDyString(1024);
+
+// build up dyString
+logTrackList(dy, trackList);
+
+// put out ~1024 bye blocks to error_log because otherwise
+// it'll chop up the lines
+char *begin = dy->string;
+char *ptr = begin;
+int count = 0;
+for(ptr=begin; ((ptr = strchr(ptr, ',')) != NULL); ptr++)
+    {
+    if (ptr - begin > 900)
+	{
+	*ptr = 0;
+	fprintf(stderr, "trackLog %d %s %s\n", count++, hgsid, begin);
+	begin = ptr+1;
+	}
+    }
+fprintf(stderr, "trackLog %d %s %s\n", count++, hgsid, begin);
+
+dyStringFree(&dy);
+}
+
 static void rAddToTrackHash(struct hash *trackHash, struct track *trackList)
 /* Add list and any children of list to hash. */
 {
 struct track *track;
 for (track = trackList; track != NULL; track = track->next)
     {
     hashAddUnique(trackHash, track->track, track);
     rAddToTrackHash(trackHash, track->subtracks);
     }
 }
 
 void highlightRegion(struct cart *cart, struct hvGfx *hvg, int insideX, int imagePixelHeight,
                        int winStart, int winEnd)
 // Highlights a region in the image.  Only done if theImgBox is not defined.
 // Thus it is done for ps/pdf and view image but the hgTracks image is highlighted via js
@@ -4414,30 +4461,33 @@
 for (track = trackList; track != NULL; track = track->next)
     {
     /* adjust track visibility based on supertrack just before load loop */
     if (tdbIsSuperTrackChild(track->tdb))
         limitSuperTrackVis(track);
 
     /* remove cart priority variables if they are set
        to the default values in the trackDb */
     if (!hTrackOnChrom(track->tdb, chromName))
         {
         track->limitedVis = tvHide;
         track->limitedVisSet = TRUE;
 	}
     }
 
+if (sameString(cfgOptionDefault("trackLog", "off"), "on"))
+    logTrackVisibilities(cartSessionId(cart), trackList);
+
 /* pre-load remote tracks in parallel */
 int ptMax = atoi(cfgOptionDefault("parallelFetch.threads", "20"));  // default number of threads for parallel fetch.
 int pfdListCount = 0;
 pthread_t *threads = NULL;
 if (ptMax > 0)     // parallelFetch.threads=0 to disable parallel fetch
     {
     findLeavesForParallelLoad(trackList, &pfdList);
     pfdListCount = slCount(pfdList);
     /* launch parallel threads */
     ptMax = min(ptMax, pfdListCount);
     if (ptMax > 0)
 	{
 	AllocArray(threads, ptMax);
 	/* Create threads */
 	int pt;