influxdata / chronograf

Open source monitoring and visualization UI for the TICK stack
https://www.influxdata.com/time-series-platform/chronograf/
Other
1.51k stars 258 forks source link

Support Kapacitor batch queries to allow historical analysis #2759

Closed love2558 closed 6 years ago

love2558 commented 6 years ago

I want to compare the current data with the data from 5 minutes ago. so,I create the alert rules, the rules are as follows:

var db = '_internal'
    var rp = 'monitor'
    var measurement = 'database'
    var groupBy = []
    var whereFilter = lambda: TRUE
    var name = 'greateralert'
    var idVar = name + ':{{.Group}}'
    var message = ' {{.ID}} {{ index .Fields "value" }} {{.Time}}'
    var idTag = 'alertID'
    var levelTag = 'level'
    var messageField = 'message'
    var durationField = 'duration'
    var outputDB = 'chronograf'
    var outputRP = 'autogen'
    var outputMeasurement = 'alerts'
    var triggerType = 'relative'
    var shift = 5m
    var crit = 6

    var data = stream
        |from()
            .database(db)
            .retentionPolicy(rp)
            .measurement(measurement)
            .groupBy(groupBy)
            .where(whereFilter)
        |eval(lambda: "numMeasurements")
            .as('value')

    var past = data
        |shift(shift)

    var current = data

    var trigger = past
        |join(current)
            .as('past', 'current')
        |eval(lambda: float("current.value" - "past.value"))
            .keep()
            .as('value')
        |alert()
            .crit(lambda: "value" > crit)
            .stateChangesOnly()
            .message(message)
            .id(idVar)
            .idTag(idTag)
            .levelTag(levelTag)
            .messageField(messageField)
            .durationField(durationField)
            .post('http://xxxxxxxx')

    trigger
        |eval(lambda: float("value"))
            .as('value')
            .keep()
        |influxDBOut()
            .create()
            .database(outputDB)
            .retentionPolicy(outputRP)
            .measurement(outputMeasurement)
            .tag('alertName', name)
            .tag('triggerType', triggerType)

    trigger
        |httpOut('output')

But the result is not what I want,It can't be compared to the past, and it always starts when the rules are created. For example,The current time is 10:15, and I create the alert rule,It can only compare 10:20 minutes with 10:15 minutes instead of 10:15 and 10:10.the result is not what I want! do you understand what I mean?

love2558 commented 6 years ago

when I create and enable alert task,the task should start to work,Not after 5 minutes or longer

goller commented 6 years ago

@love2558 thanks for writing in! I think I understand what you are saying. You would like an alert to compare to its historical data immediately rather than waiting to fill its window. In your case it fills its window after 5 minutes.

@nathanielc @desa To get immediate historical results, would the alert need to be a batch rather than a stream?

nathanielc commented 6 years ago

@goller Yes, you need to use batch in order to be able to query the historical data when the task first starts.

goller commented 6 years ago

@love2558 Ok, I'm going to change the title of this issue to be "Support kapacitor batch queries"

love2558 commented 6 years ago

@goller OK,thank you for your answer! so,chronograf UI don't support kapacitor batch queries,I need to edit the TickScript in order to change the queries type, right?

goller commented 6 years ago

@love2558 for the moment, yes. That'll be the workaround.

love2558 commented 6 years ago

@goller OK,thank you!

nhaugo commented 6 years ago

@love2558 does this not do what you are looking for? batch

love2558 commented 6 years ago

@goller @nathanielc @nhaugo sorry,I don't know how to write the TickScript in batch queries type,I need to compare current data with historical data,It's too hard.could you give me a demo?

love2558 commented 6 years ago

@goller @nathanielc @nhaugo I wrote a TickScript, but it seems to be a problem. Can you give me some advice?

var message = 'batch alerting {{.Time}} {{ index .Fields "value" }}'
var current = batch 
        |query('''
            select mean(nummeasurements) from "_internal"."monitor"."database" where time > now() - 1m
        ''')
            .every(1m)
        |eval(lambda: "mean")
                       .as('value')

var past = batch    
        |query('''
            select mean(nummeasurements) from "_internal"."monitor"."database" where time > now() - 1d - 1m and time < now() - 1d 
        ''')
            .every(1m)
        |eval(lambda: "mean")
                       .as('value')

var trigger = past
    |join(current)
        .as('past', 'current')
    |eval(lambda: float("current.mean" - "past.mean"))
        .keep()
        .as('value')
    |alert()
        .crit(lambda: "value" > 0)
        .stateChangesOnly()
        .message(message)
        .post('http://xxxxx')
love2558 commented 6 years ago

I need to compare the current data with yesterday's data for the same time period,Thank you very much!

desa commented 6 years ago

@love2558 I've made a couple adjustments to the tickscript you have above

var message = 'batch alerting {{.Time}} {{ index .Fields "value" }}'

var current = batch
    |query('select mean(nummeasurements) as value from "_internal"."monitor"."database"')
        .period(1m)
        .every(1m)
        .align()

var past = batch
    |query('select mean(nummeasurements) as value from "_internal"."monitor"."database"')
        .period(1m)
        .every(1m)
        .align()
        .offset(24h)
    |shift(24h)

var trigger = past
    |join(current)
        .as('past', 'current')
    |eval(lambda: float("current.value" - "past.value"))
        .keep()
        .as('value')
    |alert()
        .crit(lambda: "value" > 0)
        .stateChangesOnly()
        .message(message)
        .post('http://xxxxx')
love2558 commented 6 years ago

@desa Thank you very much!