Jelajahi Sumber

Merge pull request #4997 from RussWhitehead/reportBug

HPCC-7899 "Report bug" button in eclwatch WU page

Reviewed-By: Kevin Wang <kevin.wang@lexisnexis.com>
Reviewed-By: Richard Chapman <rchapman@hpccsystems.com>
Richard Chapman 11 tahun lalu
induk
melakukan
61b0d3275e

+ 17 - 0
esp/scm/ws_workunits.ecm

@@ -1412,6 +1412,22 @@ ESPresponse [exceptions_inline] WUQuerySetCopyQueryResponse
     string QueryId;
 };
 
+ESPrequest [nil_remove] WUReportBugRequest
+{
+    string WUID;
+    string ESPIPAddress;
+    string ThorIPAddress;
+    string BuildVersion;
+    string ProblemDescription;
+    string WhatChanged;
+    string WhereSlow;
+};
+
+ESPresponse [exceptions_inline] WUReportBugResponse
+{
+    [http_content("application/octet-stream")] binary thefile;
+};
+
 ESPservice [
     version("1.46"), default_client_version("1.46"),
     noforms,exceptions_inline("./smc_xslt/exceptions.xslt"),use_method_name] WsWorkunits
@@ -1482,6 +1498,7 @@ ESPservice [
     ESPmethod [resp_xsl_default("/esp/xslt/WUCopyLogicalFiles.xslt")] WUCopyLogicalFiles(WUCopyLogicalFilesRequest, WUCopyLogicalFilesResponse);
     ESPmethod WUQueryConfig(WUQueryConfigRequest, WUQueryConfigResponse);
     ESPmethod WUListQueries(WUListQueriesRequest, WUListQueriesResponse);
+    ESPmethod WUReportBug(WUReportBugRequest, WUReportBugResponse);
 };
 
 

+ 128 - 0
esp/services/ws_workunits/ws_workunitsService.cpp

@@ -3895,3 +3895,131 @@ bool CWsWorkunitsEx::onWUDeployWorkunit(IEspContext &context, IEspWUDeployWorkun
     }
     return true;
 }
+
+void CWsWorkunitsEx::addProcess(IZZIPor* zipper, Owned<IConstWorkUnit> &cwu, WsWuInfo &winfo, const char * process, MemoryBuffer &mb)
+{
+    IPropertyTreeIterator& proc = cwu->getProcesses(process, NULL);
+    ForEach (proc)
+    {
+        StringBuffer logName;
+        proc.query().getProp("@log",logName);
+        if (!logName.length())
+            continue;
+        StringBuffer pid;
+        pid.appendf("%d",proc.query().getPropInt("@pid"));
+        mb.clear();
+        if (0 == stricmp(process, "EclAgent"))
+            winfo.getWorkunitEclAgentLog(logName.str(), pid.str(), mb);
+        else if (0 == stricmp(process, "Thor"))
+            winfo.getWorkunitThorLog(logName.str(), mb);
+        else
+            return;
+
+        zipper->addContentToZIP(mb.length(), mb.bufferBase(), (char*)logName.str(), true);
+    }
+}
+
+
+bool CWsWorkunitsEx::onWUReportBug(IEspContext &context, IEspWUReportBugRequest &req, IEspWUReportBugResponse &resp)
+{
+    try
+    {
+#ifndef _USE_ZLIB
+        throw MakeStringException(ECLWATCH_CANNOT_COMPRESS_DATA,"The data cannot be compressed.");
+#else
+        Owned<IWorkUnitFactory> factory = getWorkUnitFactory(context.querySecManager(), context.queryUser());
+        Owned<IConstWorkUnit> cwu = factory->openWorkUnit(req.getWUID(), false);
+        if(!cwu.get())
+            throw MakeStringException(ECLWATCH_CANNOT_OPEN_WORKUNIT, "Cannot open workunit %s.", req.getWUID());
+
+        //Create output report file
+        StringBuffer zipFile;
+        StringBuffer userName;
+        if (context.queryUser())
+            userName.append(context.queryUser()->getName());
+        zipFile.append("bugReport_").append(req.getWUID()).append('_').append(userName.str()).append(".zip");
+        SCMStringBuffer temp;
+        StringBuffer sb;
+        sb.append("Workunit:     ").append(cwu->getWuid(temp)).append("\r\n");
+        sb.append("User:         ").append(cwu->getUser(temp).str()).append("\r\n");
+        sb.append("Build Version:").append(req.getBuildVersion()).append("\r\n");
+        sb.append("Cluster:      ").append(cwu->getClusterName(temp).str()).append("\r\n");
+        if (req.getESPIPAddress())
+            sb.append("ESP:          ").append(req.getESPIPAddress()).append("\r\n");
+        if (req.getThorIPAddress())
+            sb.append("Thor:         ").append(req.getThorIPAddress()).append("\r\n");
+        sb.append("Exceptions:   ");
+        if (0 == cwu->getExceptionCount())
+            sb.append("None\r\n");
+        else
+        {
+            sb.append("\r\n");
+            Owned<IConstWUExceptionIterator> exceptions = &cwu->getExceptions();
+            ForEach(*exceptions)
+            {
+                sb.append("\t").append(exceptions->query().getExceptionMessage(temp)).append("\r\n\r\n");
+            }
+        }
+        sb.append("Problem:      ").append(req.getProblemDescription()).append("\r\n\r\n");
+        sb.append("What Changed: ").append(req.getWhatChanged()).append("\r\n\r\n");
+        sb.append("Timing:       ").append(req.getWhereSlow()).append("\r\n\r\n");
+
+        //Zip all files together
+        {
+            IZZIPor* zipper = createZZIPor();
+#ifdef _DEBUG
+            zipper->setTraceLevel(100);
+#endif
+            StringBuffer fs;
+            //add report file to ZIP
+            fs.append("bugReport_").append(req.getWUID()).append('_').append(userName.str()).append(".txt");
+            zipper->addContentToZIP(sb.length(), (void*)sb.str(), (char*)fs.str(), false);
+
+            //add ECL query/archive to zip
+            Owned<IConstWUQuery> query = cwu->getQuery();
+            StringBuffer ecl;//String buffers containing file contents must persist until ziptofile is called !
+            if(query)
+            {
+                query->getQueryText(temp);
+                if (temp.length())
+                {
+                    fs.clear().append("bugReport_").append(req.getWUID()).append('_').append(userName.str()).append(".");
+                    fs.append(isArchiveQuery(temp.str()) ? "archive" : "ecl");
+                    ecl.append(temp.str());
+                    zipper->addContentToZIP(ecl.length(), (void*)ecl.str(), (char*)fs.str(), true);
+                }
+            }
+
+            //Add logfiles to ZIP
+            WsWuInfo winfo(context, cwu);
+            MemoryBuffer eclagentLogMB;
+            MemoryBuffer thorLogMB;
+            addProcess(zipper, cwu, winfo, "EclAgent", eclagentLogMB);
+            addProcess(zipper, cwu, winfo, "Thor", thorLogMB);
+
+            //Write out ZIP file
+            zipper->zipToFile(zipFile.str());
+        }
+
+        //Download ZIP file to user
+        Owned<IFile> f = createIFile(zipFile.str());
+        Owned<IFileIO> io = f->open(IFOread);
+        MemoryBuffer mb;
+        void * data = mb.reserve((unsigned)io->size());
+        size32_t read = io->read(0, (unsigned)io->size(), data);
+        mb.setLength(read);
+        resp.setThefile(mb);
+        resp.setThefile_mimetype(HTTP_TYPE_OCTET_STREAM);
+        StringBuffer headerStr("attachment;filename=");
+        headerStr.append(zipFile.str());
+        context.addCustomerHeader("Content-disposition", headerStr.str());
+        io->close();
+        f->remove();
+#endif
+    }
+    catch(IException* e)
+    {
+        FORWARDEXCEPTION(context, e,  ECLWATCH_INTERNAL_ERROR);
+    }
+    return true;
+}

+ 6 - 1
esp/services/ws_workunits/ws_workunitsService.hpp

@@ -21,6 +21,9 @@
 #include "ws_workunits_esp.ipp"
 #include "workunit.hpp"
 #include "ws_workunitsHelpers.hpp"
+#ifdef _USE_ZLIB
+#include "zcrypt.hpp"
+#endif
 
 class CWsWorkunitsEx : public CWsWorkunits
 {
@@ -112,8 +115,10 @@ public:
 
     bool isQuerySuspended(const char* query, IConstWUClusterInfo *clusterInfo, unsigned wait, StringBuffer& errorMessage);
     bool onWUListQueries(IEspContext &context, IEspWUListQueriesRequest &req, IEspWUListQueriesResponse &resp);
-
+    bool onWUReportBug(IEspContext &context, IEspWUReportBugRequest &req, IEspWUReportBugResponse &resp);
 private:
+    void addProcess(IZZIPor* zipper, Owned<IConstWorkUnit> &cwu, WsWuInfo &winfo, const char * process, MemoryBuffer &mb);
+
     unsigned awusCacheMinutes;
     StringBuffer queryDirectory;
     StringAttr daliServers;