Cautiones pro dispensando metrics in Kapacitor

Probabiliter nemo iam miratur cur necesse sit mensuras servitiorum colligere. Proximus gradus logicus est monita pro mensuris collectis constituere, quae te de quibuslibet deviationibus datorum per canales tuos praeferentes (inscriptiones electronicas, Slack, Telegram) certiorem facient. In servitio reservationis deversoriorum interretiali... Ostrovok.ru Omnes mensurae ex nostris officiis in InfluxDB transmittuntur et in Grafana exhibentur, ubi etiam monitiones fundamentales configurantur. Pro operibus velut "aliquid calculare et cum hoc comparare necesse est," Kapacitor utimur.

Cautiones pro dispensando metrics in Kapacitor
Kapacitor pars est acervi TICK qui mensuras ex InfluxDB tractare potest. Multas dimensiones coniungere, notitias utiles ex datis resultantibus computare, eventum ad InfluxDB rescribere, et monita ad Slack, Telegram, vel inscriptionem electronicam mittere potest.

Tota acervus imaginem elegantem et accuratam habet. Litterarum, sed semper sunt res utiles quae in manualibus explicite non memorantur. In hoc articulo, constitui colligere nonnullas tales utiles, non manifestas admonitiones (syntaxis fundamentalis TICKscipt describitur) hic) et demonstra quomodo applicari possint exemplo solvendi unum ex nostris problematibus.

Eamus!

numerorum numerorum mobilium et numerorum integrorum, errores computationis

Problema omnino commune, per fusionem solutum:

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

Utente default()

Si titulus/ager non impletur, errores computationis evenient:

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

imple iuncturam (internam contra externam)

Defalta ratione, coniunctio puncta ubi nulla data sunt (interna) abiciet.
Cum `fill('null')` iunctura externa perficietur, post quam `default()` exsequi et valores vacuas implere debes:

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

Adhuc hic exceptio est. Si una ex seriebus (res1 vel res2) in exemplo supra vacua est, series resultans (data) etiam vacua erit. Plures quaestiones GitHub de hac re sunt (1633, 1871, 6967) – emendationes exspectamus et paulum patimur.

Usus condicionum in computationibus (si in lambda sunt)

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

Quinque minuta ultima a fistula pro periodo

Exempli gratia, valores quinque minutorum proximorum cum hebdomada praecedenti comparare debes. Duas series datorum in duabus partibus separatis sumere potes, vel partem datorum ex periodo maiori extrahere:

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

Alternativa pro ultimis quinque minutis est nodum BarrierNode uti, qui notitias ante tempus definitum abscidit:

|barrier()
        .period(5m)

Exempla usus formularum Go in Nuntio

Formulae formae ex fasciculo respondent. exemplar textus, infra sunt problemata quaedam frequentia.

si aliud,

Rem ordine disponamus et ne homines textu superfluo provocemus:

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

Duae notae post punctum decimale in nuntio

Melioratio legibilitatis nuntii:

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

Variabiles in nuntio expandentes

Plura in nuntio ostendimus ut quaestioni "Cur clamat?" respondeamus.

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

Identificator unicus admonitionis

Hoc utile est commodum cum plus quam unus grex in datis est, alioquin una tantum admonitio generabitur:

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

Tractores consuetudinarii

Amplus index tractatorum "exec" includit, qui te sinit scriptum tuum cum parametris traditis (stdin) exsequi – pura creativitas!

Unum e scriptis nostris propriis est parvum scriptum Pythonicum ad notificationes ad Slack mittendas.
Primo, imaginem ex Grafana in nuntio mittere voluimus, auctoritate protecta. Deinde, "Bene" in filo pro monitione priori ab eodem grege scribere voluimus, potius quam in nuntio separato. Paulo post, errorem frequentissimum ultimorum X minutorum nuntio addere voluimus.

Thema separatum est nexus cum aliis officiis et quaelibet actiones a monitione initiatae (tantum si tua monitoria satis bene fungitur).
Exemplum descriptionis tractatoris, ubi slack_handler.py scriptum nostrum proprium est:

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 corrigere?

Optio cum exitu ad notandum

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

Observa (cli): capacitor -url hospes-vel-ip:9092 acta gradus=erroris

Optio cum httpOut

Data in cursu praesenti ostendit:

|httpOut('something')

Observa (accipe): hospes-vel-ip:9092/kapacitor/v1/tasks/nomen_officii/aliquid

Schema executionis

  • Quaeque actio arborem executionis cum numeris utilibus in forma reddit graphicvis.
  • Quadrum capimus dotem,.
  • In spectantem insere, fruamur.

Ubi alibi rastris pecunia accipere potes?

nota temporis in influxdb per scripturam retroactivam

Exempli gratia, monitionem pro summa petitionum per horam (groupBy(1h)) constituimus et volumus monitionem in influxdb notare (ut bene problematis veritatem in graphio in grafana ostendamus).

`influxDBOut()` valorem temporis ex admonitione in notam temporis scribet, ita punctum in tabula ante/post adventum admonitionis scribetur.

Cum praecisio requiritur: hanc difficultatem circumvenimus vocando tractatorem proprium, qui notitias ad influxdb cum notatione temporis currenti scribet.

Docker, construere et disponere

Cum incipit, kapacitor officia, exempla, et tractatores ex directorio in configuratione specificato, intra segmentum "[load]", onerare potest.

Ad recte creandum munus, haec tibi necessaria sunt:

  1. Nomen fasciculi - ad nomen identificationis/scripti expanditur
  2. Typus – flumen/cohors
  3. dbrp – verbum clavis ad specificandum in qua base datorum + ratione scriptum currit (dbrp "supplier"."autogen")

Si quodlibet opus batch lineam cum dbrp non continet, totum servitium incipere recusabit et honeste de eo in acta scribet.

In chronograf, contra, haec linea ibi non esse debet; per interfaciem non accipitur et errorem reddit.

Ratio constructionis receptaculi: Dockerfile cum -1 exit si lineae cum //.+dbrp adsunt, quod tibi statim causam defectus constructionis intellegere sinet.

unum multis iungo

Exemplum operis: accipe percentilem nonagesimum quintum temporis operationis servitii per hebdomadem et compara unumquodque minutum ex decem ultimis cum hoc valore.

Coniunctionem unius ad multos facere non potes; functiones "last/mean/median" super gregem punctorum nodum in rivum vertunt, et error "cannot add child matched margins: batch -> stream" reddetur.

Resultatum fasciculi, ut variabilis in expressione lambda, etiam non substituitur.

Est optio numeros necessarios ex prima fasciculo in fasciculum per UDF servandi et hunc fasciculum per Sideload onerandi.

Quid hoc solvebamus?

Habemus circiter centum praebitores deversoriorum, quorum quisque plures nexus habere potest, canales eos appellemus. Sunt circiter trecenti horum canalium, et quilibet ex eis deficere potest. Ex omnibus mensuris relatis, rationem errorum (petitiones et errores) observabimus.

Cur non Grafana?

Monita errorum in Grafana configurata plura incommoda habent. Quaedam gravia sunt, alia vero, pro condicione, neglegi possunt.

Grafana computationes interdimensionales + monita facere non potest, sed rationem (petitionum-errorum)/petitionum requirimus.

Errores foedi apparent:

Cautiones pro dispensando metrics in Kapacitor

Et minus malum si id cum petitionibus prosperis consideres:

Cautiones pro dispensando metrics in Kapacitor

Bene, ratem in servitio ante Grafana praecalculare possumus, et interdum id bene est. Sed non in nostro, quia quisque canalis suam rationem "normalem" habet, et admonitiones in valoribus staticis fundantur (eos observamus, adaptantes si frequenter admonitiones edunt).

Haec sunt exempla "normalis" pro canalibus diversis:

Cautiones pro dispensando metrics in Kapacitor

Cautiones pro dispensando metrics in Kapacitor

Punctum priorem omittamus et ponamus omnes praebitores imaginem "normalem" similem habere. Ergo, omnia nunc bene sunt, et cum monitis in Grafana uti possumus?
Possumus, sed re vera nolumus, quia unam ex his optionibus eligere debemus:
a) multa grapha pro singulis canalibus separatim facere (et ea moleste curare)
b) unum schema cum omnibus canalibus relinquere (et in lineis coloratis et monitis ad usum aptatis perdere)

Cautiones pro dispensando metrics in Kapacitor

Quomodo id fecisti?

Iterum, bonum exemplum initiale in documentis est (Computatio pretiorum per series iunctas), inspicere vel illud ut fundamentum in similibus quaestionibus uti potes.

Quod tandem fecimus:

  • Duo episodia intra paucas horas coniunge, per canales congregata;
  • seriem per greges complemus si nulla data exstant;
  • Medianam decem minutorum proximorum cum datis prioribus comparamus;
  • clamate si quid invenimus;
  • Rationes computatas et admonitiones evenerunt ad influxdb scribimus;
  • Nuntium utilem ad Slack mitte.

Mea sententia, omnia quae voluimus pulcherrime (et etiam paulo plus cum tractatoribus propriis) tandem assequi potuimus.

Inspicere potes github.com. exemplum codicis и diagramma minimale (graphviz) scriptum acceptum.

Exemplum codicis resultantis:

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 igitur est conclusio?

Kapacitor egregius est ad monitorandum et monendos plures greges, peragendo computationes additionales secundum mensuras iam notatas, peragendo actiones proprias, et exsequendo scripta (udf).

Limen ingressus non est altissimum - experire si Grafana vel alia instrumenta necessitatibus tuis non plene satisfaciunt.

Source: www.habr.com

Emptum certos hospites pro locis cum praesidio DDoS, VPS VDS servers 🔥 Eme hospitium interretiale fidum cum praesidio DDoS, servitores VPS VDS | ProHoster