Browse Source

Merge pull request #12225 from ghalliday/issue21556

HPCC-21556 Add code to describe a WuDetails filter

Reviewed-By: Shamser Ahmed <shamser.ahmed@lexisnexis.co.uk>
Reviewed-By: Richard Chapman <rchapman@hpccsystems.com>
Richard Chapman 6 years ago
parent
commit
50ba255888

+ 118 - 1
common/workunit/workunit.cpp

@@ -2465,6 +2465,12 @@ static constexpr EnumMapping propertyMappings[] = {
         { PTstatistics, "stat" }, { PTstatistics, "statistic" }, { PTattributes, "attr" }, { PTattributes, "attribute" }, { PThints, "hint" },
         { PTstatistics, "stats" }, { PTstatistics, "statistics" }, { PTattributes, "attrs" }, { PTattributes, "attributes" }, { PThints, "hints" },
         { PTnone, "none" }, { PTscope, "scope" }, { PTall, "all" }, { 0, nullptr } };
+
+
+
+WuScopeSourceFlags querySource(const char * source) { return (WuScopeSourceFlags)getEnum(source, sourceMappings, SSFunknown); }
+const char * querySourceText(WuScopeSourceFlags source) { return getEnumText(source, sourceMappings, nullptr); }
+
 WuScopeFilter::WuScopeFilter(const char * filter)
 {
     addFilter(filter);
@@ -2848,7 +2854,7 @@ void WuScopeFilter::addRequiredStat(const char * filter)
 
 WuScopeFilter & WuScopeFilter::addSource(const char * source)
 {
-    WuScopeSourceFlags mask = (WuScopeSourceFlags)getEnum(source, sourceMappings, SSFunknown);
+    WuScopeSourceFlags mask = querySource(source);
     if (mask == SSFunknown)
         throw makeStringExceptionV(0, "Unexpected source '%s'", source);
     if (!mask)
@@ -3044,6 +3050,117 @@ ScopeCompare WuScopeFilter::compareMatchScopes(const char * scope) const
 }
 
 
+StringBuffer & WuScopeFilter::describe(StringBuffer & out) const
+{
+    scopeFilter.describe(out);
+    if (requiredStats.size())
+    {
+        out.append(",where[");
+        bool first = false;
+        for (const auto & stat : requiredStats)
+        {
+            if (!first)
+                out.append(",");
+            stat.describe(out);
+            first = false;
+        }
+        out.append("]");
+    }
+
+    {
+        StringBuffer sources;
+        for (unsigned mask=1; mask; mask *= 2)
+        {
+            if (sourceFlags & mask)
+            {
+                const char * source = querySourceText((WuScopeSourceFlags)mask);
+                if (source)
+                    sources.append(",").append(source);
+            }
+        }
+        if (sources)
+            out.append(",source[").append(sources.str()+1).append("]");
+    }
+
+    if (include.nestedDepth != UINT_MAX)
+        out.appendf(",nested[%u]", include.nestedDepth);
+
+    if (include.scopeTypes)
+    {
+        out.append(",include[");
+        ForEachItemIn(i, include.scopeTypes)
+        {
+            if (i)
+                out.append(",");
+            out.append(queryScopeTypeName((StatisticScopeType)include.scopeTypes.item(i)));
+        }
+        out.append("]");
+    }
+
+    {
+        StringBuffer props;
+        if (properties == PTnone)
+            props.append(",none");
+        else if (properties == PTall)
+            props.append(",all");
+        else
+        {
+            if (properties & PTstatistics)
+                props.append(",stat");
+            if (properties & PTattributes)
+                props.append(",attr");
+            if (properties & PThints)
+                props.append(",hint");
+            if (properties & PTscope)
+                props.append(",scope");
+        }
+        out.append(",properties[").append(props.str()+1).append("]");
+    }
+
+    if (desiredStats)
+    {
+        out.append(",stat[");
+        ForEachItemIn(i, desiredStats)
+        {
+            if (i)
+                out.append(",");
+            out.append(queryStatisticName((StatisticKind)desiredStats.item(i)));
+        }
+        out.append("]");
+    }
+
+    if (desiredAttrs)
+    {
+        out.append(",attr[");
+        ForEachItemIn(i, desiredAttrs)
+        {
+            if (i)
+                out.append(",");
+            out.append(queryWuAttributeName((WuAttr)desiredAttrs.item(i)));
+        }
+        out.append("]");
+    }
+
+    if (desiredHints)
+    {
+        out.append(",hint[");
+        ForEachItemIn(i, desiredHints)
+        {
+            if (i)
+                out.append(",");
+            out.append(desiredHints.item(i));
+        }
+        out.append("]");
+    }
+
+    if (desiredMeasure != SMeasureAll)
+        out.append(",measure[").append(queryMeasureName(desiredMeasure)).append("]");
+
+    if (minVersion != 0)
+        out.appendf(",version(%" I64F "u)", minVersion);
+
+    return out;
+}
 //--------------------------------------------------------------------------------------------------------------------
 
 EnumMapping states[] = {

+ 1 - 0
common/workunit/workunit.hpp

@@ -1076,6 +1076,7 @@ public:
     WuScopeFilter & addRequiredStat(StatisticKind statKind, stat_type lowValue, stat_type highValue);
 
     void finishedFilter(); // Call once filter has been completely set up
+    StringBuffer & describe(StringBuffer & out) const; // describe the filter - each option is preceded by a comma
 
     bool includeStatistic(StatisticKind kind) const;
     bool includeAttribute(WuAttr attr) const;

+ 3 - 0
esp/services/ws_workunits/ws_wudetails.cpp

@@ -418,6 +418,9 @@ void WUDetails::processRequest(IEspWUDetailsRequest &req, IEspWUDetailsResponse
     buildWuScopeFilter(req.getScopeFilter(), req.getNestedFilter(), req.getPropertiesToReturn(),
                        req.getFilter(), scopeOptions);
 
+    StringBuffer filter;
+    PROGLOG("WUDetails: %s", wuScopeFilter.describe(filter).str());
+
     IArrayOf<IEspWUResponseScope> respScopes;
     WUDetailsVisitor wuDetailsVisitor(req.getPropertyOptions(), req.getPropertiesToReturn());
     Owned<IConstWUScopeIterator> iter = &workunit->getScopeIterator(wuScopeFilter);

+ 56 - 0
system/jlib/jstats.cpp

@@ -1187,6 +1187,17 @@ const StatisticsMapping diskWriteRemoteStatistics({StTimeDiskWriteIO, StSizeDisk
 
 //--------------------------------------------------------------------------------------------------------------------
 
+StringBuffer & StatisticValueFilter::describe(StringBuffer & out) const
+{
+    out.append(queryStatisticName(kind));
+    if (minValue == maxValue)
+        out.append("=").append(minValue);
+    else
+        out.append("=").append(minValue).append("..").append(maxValue);
+    return out;
+}
+//--------------------------------------------------------------------------------------------------------------------
+
 class Statistic
 {
 public:
@@ -2897,6 +2908,51 @@ int ScopeFilter::compareDepth(unsigned depth) const
     return 0;
 }
 
+StringBuffer & ScopeFilter::describe(StringBuffer & out) const
+{
+    if ((minDepth != 0) || (maxDepth != UINT_MAX))
+    {
+        if (minDepth == maxDepth)
+            out.appendf(",depth(%u)", minDepth);
+        else
+            out.appendf(",depth(%u,%u)", minDepth, maxDepth);
+    }
+    if (scopeTypes)
+    {
+        out.append(",stype[");
+        ForEachItemIn(i, scopeTypes)
+        {
+            if (i)
+                out.append(",");
+            out.append(queryScopeTypeName((StatisticScopeType)scopeTypes.item(i)));
+        }
+        out.append("]");
+    }
+    if (scopes)
+    {
+        out.append(",scope[");
+        ForEachItemIn(i, scopes)
+        {
+            if (i)
+                out.append(",");
+            out.append(scopes.item(i));
+        }
+        out.append("]");
+    }
+    if (ids)
+    {
+        out.append(",id[");
+        ForEachItemIn(i, ids)
+        {
+            if (i)
+                out.append(",");
+            out.append(ids.item(i));
+        }
+        out.append("]");
+    }
+    return out;
+}
+
 void ScopeFilter::finishedFilter()
 {
     //If scopeTypes are provided, then this code ensure that any scopes and ids match them

+ 2 - 0
system/jlib/jstats.h

@@ -273,6 +273,7 @@ public:
     }
 
     StatisticKind queryKind() const { return kind; }
+    StringBuffer & describe(StringBuffer & out) const;
 
 protected:
     StatisticKind kind;
@@ -324,6 +325,7 @@ public:
 
     const StringArray & queryScopes() const { return scopes; }
     bool matchOnly(StatisticScopeType scopeType) const;
+    StringBuffer & describe(StringBuffer & out) const;
 
 protected:
     void intersectDepth(unsigned _minDepth, unsigned _maxDepth);