Regression analysis: detect service disruptions using trace logs
#make-series #series_fit_line #series_fit_2lines
This example demonstrates how to create an automated detector for service disruptions, based exclusively on an application's trace logs. The detector seeks abnormal and sudden increases in the relative amount of error/warning traces in our application compared to Info/Verbose.
Two techniques are used to evaluate the service status based on trace logs data:
- Conversion of semi-structured textual trace logs into a metric, representing the ratio between semantically positive/negative trace lines.
- Advanced step-jump detection using time-series analysis, with a 2-line linear regression.
let startDate = startofday(datetime("2017-02-01")); let endDate = startofday(datetime("2017-02-07")); let minRsquare = 0.8; // Tune the sensitivity of the detection sensor. Values close to 1 indicate very low sensitivity. // Count all Good (Verbose + Info) and Bad (Error + Fatal + Warning) traces, per day traces | where timestamp > startDate and timestamp < endDate | summarize Verbose = countif(severityLevel == 0), Info = countif(severityLevel == 1), Warning = countif(severityLevel == 2), Error = countif(severityLevel == 3), Fatal = countif(severityLevel == 4) by bin(timestamp, 1d) | extend Bad = (Error + Fatal + Warning), Good = (Verbose + Info) // Determine the ratio of bad traces, from the total | extend Ratio = (todouble(Bad) / todouble(Good + Bad))*10000 | project timestamp , Ratio // Create a time series | make-series RatioSeries=any(Ratio) default=0 on timestamp in range(startDate , endDate -1d, 1d) by 'TraceSeverity' // Apply a 2-line regression to the time series | extend (RSquare2, SplitIdx, Variance2,RVariance2,LineFit2)=series_fit_2lines(RatioSeries) // Find out if our 2-line is trending up or down | extend (Slope,Interception,RSquare,Variance,RVariance,LineFit)=series_fit_line(LineFit2) // Check whether the line fit reaches the threshold, and if the spike represents an increase (rather than a decrease) | project PatternMatch = iff(RSquare2 > minRsquare and Slope>0, "Spike detected", "No Match")