Cautiones pro dispensando metrics in Kapacitor

Verisimile est, hodie nemo quaerit cur opus sit officium metrice colligere. Proximus gressus logicus est intentus pro metricis collectis, qui notificabit de omnibus deflexionibus in canalibus commodas tibi (mail, Slack, Telegram). In online deversorium libri muneris Ostrovok.ru omnia metrica officia nostra in InfluxDB infunduntur et in Grafana exponuntur, ac praecipuae vigilantiae etiam ibi configurantur. Ad munera sicut "aliquid computare debes et cum eo compara", Kapacitor utimur.

Cautiones pro dispensando metrics in Kapacitor
Kapacitor pars est ACERVUS TICK, quae metrice ab InfluxDB procedere potest. Plures mensuras simul (coniungere), computare aliquid utile ex data recepta, scribe exitum ad InfluxDB, vigilantem mittere ad Slack/Telegram/mail.

Totus ACERVUS est frigus et digerente Litterarumsed semper erunt utilia quae in manibus non expresse indicantur. In hoc articulo, numerum talium utilium, non manifestorum apicibus (the basic syntax of TICKscipt descriptum, colligere decrevi. hic) et ostende quomodo applicari possint exemplo solvendi unum e nostris quaestionibus.

Eamus!

innatet & int, calculi errores

Problema absolute vexillum, per castella solvitur;

var alert_float = 5.0
var alert_int = 10
data|eval(lambda: float("value") > alert_float OR float("value") < float("alert_int"))

Usus default ()

Si tag/agro non impletur, calculi errores occurrent;

|default()
        .tag('status', 'empty')
        .field('value', 0)

imple in join (exteriore nobis interiore)

Defalta, coniunge puncta ubi nulla notitia (interiora).
Cum satiata ('nulli'), iunctura externa perficietur, post quam defaltam facere debes et in inanibus bonis imple;

var data = res1
    |join(res2)
        .as('res1', 'res2)
        .fill('null')
    |default()
        .field('res1.value', 0.0)
        .field('res2.value', 100.0)

Est etiamnum hic nuance. In exemplo supra, si una series (res1 vel res2) vacua est, series consequentis vacua erit. Plures tesserae in Github hoc loco sunt.1633, 1871, 6967) β€” exspectamus figa et paulum patimur.

Condiciones in calculis utendo (si in lambda)

|eval(lambda: if("value" > 0, true, false)

Tandem quinque minuta ad tempus a pipeline

Exempli gratia, valores ultimae quinque minutae cum priore septimana comparare debes. Duas batches notitiarum in duas batches separatas accipere potes vel ex parte amplioris temporis extrahendi notitiarum;

 |where(lambda: duration((unixNano(now()) - unixNano("time"))/1000, 1u) < 5m)

Vel potest dici pro quinque ultimis minutis uti BarrierNode, quae notitias intercludit ante tempus determinatum;

|barrier()
        .period(5m)

Exempla usus Go template in relatum

Formulae correspondent forma ex sarcina text.templateInfra sunt quaedam frequenter obviae sollicitat.

si aliud,

res ordine disponimus nec felis populum iterum cum textu iterum:

|alert()
    ...
    .message(
        '{{ if eq .Level "OK" }}It is ok now{{ else }}Chief, everything is broken{{end}}'
    )

Duo numeri post punctum in nuntio

Improving readability of the message:

|alert()
    ...
    .message(
        'now value is {{ index .Fields "value" | printf "%0.2f" }}'
    )

Expanding variables in nuntio

Plura informationes ostendimus in nuntio respondendi quaestioni "Quare clamat"?

var warnAlert = 10
  |alert()
    ...
    .message(
       'Today value less then '+string(warnAlert)+'%'
    )

Unique erecti identifier

Hoc necessarium est, cum plures globi in notitiis sint, aliter intenti tantum generabuntur;

|alert()
      ...
      .id('{{ index .Tags "myname" }}/{{ index .Tags "myfield" }}')

More tracto's

Magnum tractorium tractatorum includunt exec, quod tibi permittit ut scripturam tuam exsequias cum parametris praeteritis (stdin) - creativity et nihil amplius!

Una ex nostris moribus parva est scriptor Python ad notificationes ad remissas mittendas.
In primis voluimus mittere picturam authenticam conservandi grafana per nuntium. Postea scribe OK in sequela ad priorem intentum ab eodem coetu et non quasi nuntium separatum. Paulo post - ad nuntium adde errorem frequentissimum in ultimis X momentis.

Locus separatus communicatio est cum aliis officiis ac actionibus quibusvis inceptis (tantum si satis bene vigilantia tua operatur).
Exemplum tracto descriptionis, ubi remissa_handler.py scriptum est nostra propria:

topic: slack_graph
id: slack_graph.alert
match: level() != INFO AND changed() == TRUE
kind: exec
options:
  prog: /sbin/slack_handler.py
  args: ["-c", "CHANNELID", "--graph", "--search"]

Quomodo lusione?

Optio cum iniuriarum output

|log()
      .level("error")
      .prefix("something")

Watch (cli): kapacitor -url host-seu-ip*:9092 acta lvl=errore

Optio cum httpOut

Ostendit data in pipeline current:

|httpOut('something')

vigilate (adepto); host-seu-ip*: 9092/kapacitor/v1/officium/task_name/aliquid

Supplicium consilium

  • Unumquodque negotium reddit exsecutionem ligni cum utilibus numeris in forma graphviz.
  • Accipies obstructionum dotem,.
  • Crustulum in videntium; frui.

unde aliud rastrum accipere potes ?

indicatione in influxdb in writeback

Exempli gratia, summam petitionum per horae (groupBy (1h)) erectam constituimus et intentum quod in influxdb factum est memorare cupimus (ad pulchre hoc problema de grapha in grafana demonstrandum).

influxDBOut() tempus valorem ab intenti ad tempus scribet, ideoque punctum in chart ante/serius quam intenti pervenit.

Cum accuratio requiritur: circum hoc problema laboramus appellando tractatorem morem, qui notitias scribet ad influxdb cum indicatione temporis currentis.

docker, aedificare ac instruere

In satus, kapacitor muneribus, exemplaribus et tracto onerare potest e presul in config in clausura determinato.

Ad recte faciendum negotium, sequentia debes:

  1. File name - expanded in scriptor id / nomen
  2. Typus - amnis / batch
  3. dbrp - keyword ut indicant database + consilium scriptor decurrit in (dbrp "supplier." "autogen")

Si massae alicuius operis lineam cum dbrp non contineat, tota religio recusabit incipere et honeste de ea scribere in sextario.

In chronographo contra haec linea non debet esse, non per medium accipitur et errorem generat.

Hack cum aedificaret continens: Dockerfile exit cum -1 si lineae sunt cum //.+dbrp, quae statim intelleges te sinet causam defectionis cum aedificatione convenire.

iungere unum multis

Exemplum muneris: debes accipere 95th centensimum tempus operandi operantis per hebdomadem, singula minuta ultimi 10 cum hoc valore compara.

Non potes unum ad multa iungere, novissime/medium/medianum super globo punctorum nodi in rivum vertit, error "puerum margines inaequales addere non potest: batch -> rivus" revertitur.

Effectus massae, ut variabilis in expressione lambda, etiam non substituitur.

Optandum est ut numeros necessarios servet a fasciculo primo ad fasciculum per udf et hunc fasciculum per sideload onerant.

Quid hoc solvemus?

Praebitores circiter 100 deversoriorum habemus, quisque eorum plures nexus habere potest, canalem vocemus. Circiter 300 hi canales sunt, singuli canales excidere possunt. Inter omnia metrica exposita, errorem rate (petitiones et errores monent).

Quidni grafana?

Error summis configuratus in Grafana plura incommoda habet. Quaedam critica sunt, quaedam ut pro re nata fallat.

Grafana nescit computare inter mensuras + erectiones, sed rogationibus (petitiones-errorum) indigemus.

Errores sordidi spectant;

Cautiones pro dispensando metrics in Kapacitor

Minusque mali est, cum in secundis petitionibus spectatur;

Cautiones pro dispensando metrics in Kapacitor

Bene, prae-calculare possumus ratem in servitio ante grafana, et in aliquibus casibus hoc faciet. Sed mi neque, nam... pro unoquoque canali sua ratio consideratur "normalis", et summae secundum valores staticos operantur (illas oculis exspectamus, eas si frequentes sunt erecti mutantur).

Haec sunt exempla "normalis" pro diversis canalibus:

Cautiones pro dispensando metrics in Kapacitor

Cautiones pro dispensando metrics in Kapacitor

Praecedens punctum neglegimus et imaginem "normalem" esse similem omnibus praebitoribus pono. Nunc omnia denique sunt, et per summis in grafana possumus accipere?
Possumus, sed vere non vis, quia unum ex optionibus eligere debemus:
a) graphs multum facit ad singulas partes alveum (et dolens eos comitantur)
b) unam chartulam cum omnibus canalibus (et deerrare in lineis vario et summis nativus)

Cautiones pro dispensando metrics in Kapacitor

Quomodo id fecisti?

Iterum exemplum in documentis est bonum principium.Calculandum rates per seriem iunctis) , vel accipi vel pro fundamento in similibus quaestionibus levari potest.

Quod in fine fecimus;

  • iunge binas series paucis horis, canalibus associatas;
  • comple in serie, si nulla notitia;
  • comparare mediana ultimae X minutae cum praecedenti notitia;
  • clamamus si aliquid invenimus;
  • calculis et summis in influxdb occurrentibus scribimus;
  • nuntium mittere utilem remissam.

Opinor, omnia assequi potuimus ut ad finem (et vel paulo more tracto) quam pulchre efficere potuimus.

Potes intueri github.com codice exemplum ΠΈ minima circuitu (graphviz) inde a script.

Exemplum de codice consequens:

dbrp "supplier"."autogen"
var name = 'requests.rate'
var grafana_dash = 'pczpmYZWU/mydashboard'
var grafana_panel = '26'
var period = 8h
var todayPeriod = 10m
var every = 1m
var warnAlert = 15
var warnReset = 5
var reqQuery = 'SELECT sum("count") AS value FROM "supplier"."autogen"."requests"'
var errQuery = 'SELECT sum("count") AS value FROM "supplier"."autogen"."errors"'

var prevErr = batch
    |query(errQuery)
        .period(period)
        .every(every)
        .groupBy(1m, 'channel', 'supplier')

var prevReq = batch
    |query(reqQuery)
        .period(period)
        .every(every)
        .groupBy(1m, 'channel', 'supplier')

var rates = prevReq
    |join(prevErr)
        .as('req', 'err')
        .tolerance(1m)
        .fill('null')
    // заполняСм значСния нулями, Ссли ΠΈΡ… Π½Π΅ Π±Ρ‹Π»ΠΎ
    |default()
        .field('err.value', 0.0)
        .field('req.value', 0.0)
    // if Π² lambda: считаСм Ρ€Π΅ΠΉΡ‚, Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ссли ошибки Π±Ρ‹Π»ΠΈ
    |eval(lambda: if("err.value" > 0, 100.0 * (float("req.value") - float("err.value")) / float("req.value"), 100.0))
        .as('rate')

// записываСм посчитанныС значСния Π² ΠΈΠ½Ρ„Π»ΡŽΠΊΡ
rates
    |influxDBOut()
        .quiet()
        .create()
        .database('kapacitor')
        .retentionPolicy('autogen')
        .measurement('rates')

// Π²Ρ‹Π±ΠΈΡ€Π°Π΅ΠΌ Π΄Π°Π½Π½Ρ‹Π΅ Π·Π° послСдниС 10 ΠΌΠΈΠ½ΡƒΡ‚, считаСм ΠΌΠ΅Π΄ΠΈΠ°Π½Ρƒ
var todayRate = rates
    |where(lambda: duration((unixNano(now()) - unixNano("time")) / 1000, 1u) < todayPeriod)
    |median('rate')
        .as('median')

var prevRate = rates
    |median('rate')
        .as('median')

var joined = todayRate
    |join(prevRate)
        .as('today', 'prev')
    |httpOut('join')

var trigger = joined
    |alert()
        .warn(lambda: ("prev.median" - "today.median") > warnAlert)
        .warnReset(lambda: ("prev.median" - "today.median") < warnReset)
        .flapping(0.25, 0.5)
        .stateChangesOnly()
        // собираСм Π² message ссылку Π½Π° Π³Ρ€Π°Ρ„ΠΈΠΊ Π΄Π°ΡˆΠ±ΠΎΡ€Π΄Π° Π³Ρ€Π°Ρ„Π°Π½Ρ‹
        .message(
            '{{ .Level }}: {{ index .Tags "channel" }} err/req ratio ({{ index .Tags "supplier" }})
{{ if eq .Level "OK" }}It is ok now{{ else }}
'+string(todayPeriod)+' median is {{ index .Fields "today.median" | printf "%0.2f" }}%, by previous '+string(period)+' is {{ index .Fields "prev.median" | printf "%0.2f" }}%{{ end }}
http://grafana.ostrovok.in/d/'+string(grafana_dash)+
'?var-supplier={{ index .Tags "supplier" }}&var-channel={{ index .Tags "channel" }}&panelId='+string(grafana_panel)+'&fullscreen&tz=UTC%2B03%3A00'
        )
        .id('{{ index .Tags "name" }}/{{ index .Tags "channel" }}')
        .levelTag('level')
        .messageField('message')
        .durationField('duration')
        .topic('slack_graph')

// "today.median" Π΄ΡƒΠ±Π»ΠΈΡ€ΡƒΠ΅ΠΌ ΠΊΠ°ΠΊ "value", Ρ‚Π°ΠΊΠΆΠ΅ пишСм Π² ΠΈΠ½Ρ„Π»ΡŽΠΊΡ ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Π΅ Ρ„ΠΈΠ»Π΄Ρ‹ Π°Π»Π΅Ρ€Ρ‚Π° (keep)
trigger
    |eval(lambda: "today.median")
        .as('value')
        .keep()
    |influxDBOut()
        .quiet()
        .create()
        .database('kapacitor')
        .retentionPolicy('autogen')
        .measurement('alerts')
        .tag('alertName', name)

Quid est conclusio?

Kapacitor magnus est ad vigilantia-conationes faciendas cum fasciculo gregum, adiectis calculis faciendo positis in metricis iam memoratis, agendis consuetudinibus et scriptis currentibus faciendo (udf).

Claustrum ad ingressum non valde altum est - experire si grafana vel alia instrumenta, tuis desideriis plene non satisfaciunt.

Source: www.habr.com