[CA80][V543] Elasticsearch/Logstash/Kibana vs Meratronik V543 i CA80 - dwa światy razem.

Kącik dla elektroniki retro - układy, urządzenia, podzespoły, literatura itp.
Awatar użytkownika
tasza
Geek
Geek
Posty: 1082
Rejestracja: czwartek 12 sty 2017, 10:24
Kontaktowanie:

[CA80][V543] Elasticsearch/Logstash/Kibana vs Meratronik V543 i CA80 - dwa światy razem.

Postautor: tasza » sobota 22 cze 2019, 20:42

♬ ☘ Moja muzyka do kodowania ♬ ♬ ♬ ☘
♫ ♩ ♪ Behemoth ⚡ ☘ ⚡ Blow Your Trumpets Gabriel ♪ ♩ ♫
https://youtu.be/Czx-OIyrQwQ


Mam wrażenie, że kiedyś o tym już wspominałam - łączenie techniki współczesnej i klamotów w klimatach retro to dla mnie frajda sama w sobie, a osiągalne efekty są czasem dość ciekawe. Z wymienionym w tytule oprogramowaniem Elasticsearch, Kibana i Logstash spotkałam się na projekcie w fabryce, oj spory czas temu, okazało się to na tyle intrygujące, że zaczęłam też drążyć temat w tak zwanych domowych pieleszach, no i mamy co następuje - zabawowo zorientowany system akwizycji danych wykorzystujący nowoczesne i "modne" oprogramowanie, a w formie końcówek obiektowych znajdziemy znane już dinozaury CA80 i V543.

W moim odczuciu, to forum ma środek ciężkości przeniesiony na elektronikę i oprogramowanie embedded zatem, niejako z konieczności dwa słowa rozjaśnienia czym są składniki stosu ELK, tak zupełnie skrótowo.

Logstash - to oprogramowanie przyjmujące dane z różnych źródeł i sprowadzające pakiet informacji do wspólnego mianownika (kanonizacja, uspójnienie formatu) akceptowalnego przez bazę Elasticsearch. Pozyskiwanie danych odbywa się w sposób pasywny, tylko czytając ze źródła (stdin,http,log4j) lub aktywny (exec, pipe, http_pool) gdzie potencjalne źródło zdarzeń jest odpytywane z ewentualnych nowości.

Elasticsearch - megacwane narzędzie stanowiące silnik wyszukiwania, są kryteria kwalifikujące go jako `non-SQL database` i to jest mi najbliższe. Dane przechowywane są w tzw. indeksach (analogia tabel), pojedyncze rekordy to odpowiednio sformatowane dokumenty JSON. Do tego dochodzi cała sprytna infrastruktura zarządzająca tymi danymi, zapewniająca szybki dostęp zarówno do informacji bieżących jak i archiwalnych (hot-warm-cold architecture).

Kibana - fajne, estetyczne i bardzo funkcjonalnie opakowanie graficzne do powyższych, stanowiące zarówno warstwę prezentacji (logi,wykresy, dashboardy) jaki i GUI do podstawowych zadań utrzymaniowych czyli zarządzanie zasobami i cyklem życia indeksów.

Raczej nie ma sensu powielać informacji już umieszczonych w sieci, zatem poniżej garść linków z których ja się uczyłam, proszę przeglądnać i ewentualnie googlować dalej:

:arrow: https://logz.io/learn/complete-guide-elk-stack/
:arrow: https://blog.gutek.pl/2017/01/23/elastic-logstash/
:arrow: http://krzysztofjelonek.net/elk-stack-d ... ia-logami/
:arrow: https://www.elastic.co/guide/en/logstas ... -ruby.html
:arrow: https://dzone.com/articles/kibana-tutor ... ted-part-1
:arrow: https://grokconstructor.appspot.com/do/automatic

W tym opisie opisie wykorzystałam oprogramowanie w wersji 5.6, biorąc pod uwagę dynamiczny rozwój całego stosu (bo za tym stoi naprawdę spora kasa) jest to edycja nieco zapyziała i nie do końca nadaje się do ludzi. No ale ma tę zaletę, że cały stack uruchomi mi się na maszynie z 4GB RAM i 32-bitowym Linux Mint 17. Jeżeli ktoś zechce podejść do zagadnienia i ma zaplecze sprzętowe, proszę korzystać z najnowszych nitek 7.1.x, choćby w przypadku GUI Kibana różnice w funkcjonalnościach są drastyczne i momentami wyrywają z majtek.

przygotowania - CA80

Cała zabawka ma mierzyć i logować zmiany temperatury, zacznijmy zatem od czujnika i pobierania z niego informacji. Tu wybór był oczywisty, choćby z racji tego, że instalacja ciągle siedzi za oknem na parapecie (od południowej strony) - kostka MCP9700 od Microchip. Ktoś już tu na forum to tym układzie pisał, więc [szukaj], a w połączeniu z CA80 sprawuje się wyśmienicie :arrow: http://bienata.waw.pl/ca806.php , druciaczek z ośmiobitowym TLC549 wygląda pociesznie:

00_IMG_5780.JPG


Oprogramowanie dla CA80 zostało przygotowane mocno na motywach opowieści o kostce Z80-SIO, w sumie to wydarzyły się trzy ważne funkcje - odczytywanie przetwornika A/C, odczytywanie pokładowego czasu i daty oraz logowanie w ustalonym formacie na zdalnej, szeregowej konsoli. A zatem mamy kolejno - przetwornik:

sio_demo_irq4_logstash.c pisze:

Kod: Zaznacz cały

unsigned char getADC(void) __naked {
    __asm
        ld  A,#0x00
        out (0xE2),A        ; PC-0xE2
        ; reset vars
        ld  B,#8            ; bits
        ld  C,#0            ; keep A/D val.
getADC$0:
        ; get bit from ADC
        in  A,(0xE2)
        and A,#0x80       
        or A,C                  ; A := A|C
        rlca                    ; >> wziuuuu
        ld C,A                  ; put in C back     
        ; clock _/~\_
        ld  A,#0x02
        out (0xE2),A     ; /cs = L, CLK = H
        ld  A,#0x00
        out (0xE2),A     ; /cs = L, CLK = L
        ; get next bit
        djnz getADC$0
        ; /CS = H
        ld  A,#0x01
        out (0xE2),A     ; /cs = H, CLK = L
        ld L,C                  ; result       
        ret
    __endasm;
}


Odczytywanie czasu lokalnego z zegarka napędzanego przerwaniem NMI:

sio_demo_irq4_logstash.c pisze:

Kod: Zaznacz cały

void getSystemTime(struct tm *pT) {
    pT->tm_sec = *((unsigned char*)0xFFED);
    pT->tm_min = *((unsigned char*)0xFFEE);
    pT->tm_hour = *((unsigned char*)0xFFEF);       
    pT->tm_mday = *((unsigned char*)0xFFF1);
    pT->tm_mon = *((unsigned char*)0xFFF2);
    pT->tm_year = *((unsigned char*)0xFFF3);       
    pT->tm_hundredth = *((unsigned char*)0xFFEC);       
}


No i wisienka na torcie - logowanie na konsole:

sio_demo_irq4_logstash.c pisze:

Kod: Zaznacz cały

void log( const char *fmt, ... ) {
    va_list argptr;   
    struct tm  t;
    getSystemTime( &t );
    sprintf(
        szLogTxtBuff,
        "[20%02X-%02X-%02XT%02X:%02X:%02X.%02X][%s][%d]",
        t.tm_year,
        t.tm_mon,
        t.tm_mday,
        t.tm_hour,
        t.tm_min,
        t.tm_sec,
        t.tm_hundredth,
        __FILE__,
        __LINE__
    );
    putStr (1, szLogTxtBuff );
    va_start(argptr, fmt);   
    vsprintf( szLogTxtBuff, fmt, argptr );   
    va_end(argptr);
    putStr (1, szLogTxtBuff );
    putStr (1, "\n" );
}


Tu jak widać podziękowałam wszelkim perwersyjnym makrom, jest sobie zwykła funkcja ze zmienną ilością argumentów i póki co działa to całkiem sprawnie.

Zależało mi niezmiernie, aby CA80 był w stanie pisać po konsoli, ale z drugiej strony niespecjalnie uśmiechało mi się dłubanie nowego, dedykowanego programiku. Z pomocą przyszedł Linux, poleceniem

bash pisze:

Kod: Zaznacz cały

stty -F /dev/ttyUSB1 speed 38400


ustawiłam sobie szybkość transmisji, a ciągły odczyt strumienia danych realizowała jedna linijka:

bash pisze:

Kod: Zaznacz cały

cat /dev/ttyUSB1


przygotowania - Meratronik V543

Tu także nieco na skróty, bo ja z tych w gorącej wodzie kąpanych - przeróbka (klon) istniejącego już oprogramowania dla Raspberry PI-Zero, będącego sercem interfejsu SCPI ( :arrow: https://github.com/bienata/piv543scpi/b ... /v543lxi.c ) Po prostu wywaliłam całą cześć odpowiedzialną za komunikację sieciową, polecenie SCPI podaje się jako parametr wywołania programiku, wynik wystawiany jest na stdout, co umożliwia jego zabranie do dalszej obróbki. Kod po zabiegach sprowadza się do poniższego:

v543lxicli.c pisze:

Kod: Zaznacz cały

int main( int argc, char *argv[] ) {
    char commandBuffer[ 64 ];
    char responseBuffer[ 64 ];     
    wiringPiSetup () ;     
    pinMode ( LINE_READY, INPUT );
    pinMode ( LINE_CLK,   OUTPUT );
    pinMode ( LINE_LOAD,  OUTPUT );     digitalWrite( LINE_LOAD, HIGH );   
    pinMode ( LINE_DATA,  INPUT );      digitalWrite( LINE_CLK, HIGH );       
    pinMode ( LED_READY, OUTPUT ); 
    pinMode ( LED_SCPI, OUTPUT );
    memset( commandBuffer, 0x00, sizeof(commandBuffer) );
    memset( responseBuffer, 0x00, sizeof(responseBuffer) );       
    onMeterReadyInterrupt();
    strcpy ( commandBuffer, argv [1] );   
    makeLower( commandBuffer );               
    processScpiCommand ( trim( commandBuffer ), responseBuffer );   
    printf( responseBuffer );
    return 0;
}


A jego zdalne wywołanie wygląda równie prosto:

bash pisze:

Kod: Zaznacz cały

ssh -i ~/.ssh/otoja-dev pi@v543 '/home/pi/piv543scpi/v543lxicli ":measure:voltage:dc?" '


Aha, bo tu może ktoś mieć problem - aby uniknąć męczącej palcówki z hasłem do PI (co z resztą przy systemowym wywoływaniu poleceń byłoby cokolwiek trudne) dorobiłam logowanie via kluczyk, czyli na moim dużym linuksie - generacja i zaaplikowanie klucza:

bash pisze:

Kod: Zaznacz cały

ssh-keygen -f ~/.ssh/otoja-dev
ssh-copy-id -i ~/.ssh/otoja-dev pi@v543


a potem, jazda! wszystko pięknie się woła:

bash pisze:

Kod: Zaznacz cały

ssh -i ~/.ssh/otoja-dev pi@v543 'ls -l'
ssh -i ~/.ssh/otoja-dev pi@v543 'ps -A'
ssh -i ~/.ssh/otoja-dev pi@v543 'df -h'


Polecam powyższe, naprawdę fajnie to działa i można zdalne komendy wołać z poziomu skryptu zupełnie jak lokalne.

Na koniec obrazek jaki to war sobie był wtedy za oknem - 1.0045V to jest jak łatwo obliczyć - 50`C, no masakra normalnie.

01_temp-0.jpg


dwa światy

Mamy jakoś ogarniętą niskopoziomową cześć sprzętową, można zatem przejść do obłaskawiania nowobogackiego oprogramowania stosu Elastic - ELK. Wymowny rysunek za poziomie praca-technika klasa 5 szkoły podstawowej mamy poniżej:

02__logstash-archi.png


I tu kolejno - jak ta maszyneria działa.

Logstash zbiera dane (zdarzenia-eventy) z dwóch rozłącznych strumieni CA80 i V543, konfiguracja je koordynująca jest następująca:

logstash-6.5.0/config/pipelines.yml pisze:

Kod: Zaznacz cały

- pipeline.id: ca80
  queue.type: persisted
  pipeline.workers: 1
  pipeline.batch.size: 1 
  path.config: "ca80.conf"

- pipeline.id: v543
  queue.type: persisted
  pipeline.workers: 1
  pipeline.batch.size: 1 
  path.config: "v543.conf"


Dane z Meratronika są pozyskiwane w sposób aktywny, Logstash z zadanym interwałem czasu wykonuje zdalne polecenie i asymiluje jego wyniki, tym zajmuje się sekcja input konfiguracji strumienia. Drobna trudność polega na tym, że idąc na łatwiznę pozostawiłam naukowy format float xE+/-y, co jest tak na wprost średnio zjadliwe przez funkcje formatujące Logstasha. Tak więc z sekcji filter konieczne było dopisanie konwertera formatów danych (tu w roli głównej Ruby), przy okazji odjęłam te 500mV czujnika MCP9700 wynikowo dostając temperaturę z stopniach C. Wyjście potoku - to przekazanie danych do instancji Elasticsearch, pod ustaloną arbitralnie nazwę indeksu. Wskazanie dodatkowego kodera rubydebug ułatwia niezmiernie wszelkie poprawki, na konsoli będziemy mieli ładnie sformatowane dokumenty JSON, dokładnie takie, jak polecą do bazy.

logstash-6.5.0/v543.conf pisze:

Kod: Zaznacz cały

input {
    exec {
        command => "/home/otoja/elk/logstash-6.5.0/callV543.sh"
        interval => 10
    }
}
filter {
    grok { 
        match => { "message" => "%{GREEDYDATA:fRawValue}" }
    }
    ruby {
        code => "event.set( 'fTemperature', (( event.get('fRawValue').to_f - 0.5 ) * 100).round(2) )"
    }
}
output { 
    elasticsearch {
        hosts => ["localhost:9200"]
        index => ["v543daq-%{+YYYY.MM.dd}"]
    } 
    stdout {
        codec => rubydebug
    }
}


No i oczywiście próbka danych:

stdout pisze:

Kod: Zaznacz cały

{
    "fTemperature" => 23.42,
      "@timestamp" => 2019-06-22T17:41:40.277Z,
            "host" => "icequeen",
         "command" => "/home/otoja/elk/logstash-6.5.0/callV543.sh",
         "message" => "+7.342000E-01\n",
        "@version" => "1",
       "fRawValue" => "+7.342000E-01\n"
}
{
    "fTemperature" => 23.41,
      "@timestamp" => 2019-06-22T17:41:49.633Z,
            "host" => "icequeen",
         "command" => "/home/otoja/elk/logstash-6.5.0/callV543.sh",
         "message" => "+7.341000E-01\n",
        "@version" => "1",
       "fRawValue" => "+7.341000E-01\n"
}
{
    "fTemperature" => 23.4,
      "@timestamp" => 2019-06-22T17:41:59.618Z,
            "host" => "icequeen",
         "command" => "/home/otoja/elk/logstash-6.5.0/callV543.sh",
         "message" => "+7.340000E-01\n",
        "@version" => "1",
       "fRawValue" => "+7.340000E-01\n"
}


Teraz CA80, tu sprawa jest prosta, choć uprzedzam - wejście typu PIPE działa tylko na linux, konfiguracja:

logstash-6.5.0/ca80.conf pisze:

Kod: Zaznacz cały

input {
    pipe {
        command => "cat /dev/ttyUSB1"
    }
}
filter {
    grok { 
        match => { "message" => "\[%{TIMESTAMP_ISO8601:localTime}\]\[%{GREEDYDATA:sourceFile}\]\[%{NUMBER:sourceLine}\]%{GREEDYDATA:anyText}" }
    }
    if [anyText] =~ /Tout/ {
        mutate {
            split => ["anyText", "= "]
            add_field => { "outDoorTemp" => "%{anyText[1]}" }
        }
        mutate {       
            convert => { "outDoorTemp" => "integer" }       
            remove_field => [ "anyText" ]
            remove_field => [ "sourceLine" ]                       
            add_field => { "type" => "DAQ" }
        }       
    }
}
output { 
    if [type] == "DAQ" {
        elasticsearch {
            hosts => ["localhost:9200"]
            index => ["ca80daq-%{+YYYY.MM.dd}"]
        } 
    } else {
        elasticsearch {
            hosts => ["localhost:9200"]
            index => ["ca80log-%{+YYYY.MM.dd}"]
        } 
    }
    stdout {
        codec => rubydebug
    }
}


Tu wielkich czarów nie ma, choć sztuczka drobna jest - separacja strumienia na dwa indeksy. Zerknijmy na dane, jakich dostarcza CA80 - to pole `message`:

stdout pisze:

Kod: Zaznacz cały

{
      "localTime" => "2019-06-22T19:53:26.44",
       "@version" => "1",
    "outDoorTemp" => 23,
           "type" => "DAQ",
        "command" => "cat /dev/ttyUSB1",
           "host" => "icequeen",
     "@timestamp" => 2019-06-22T17:53:36.636Z,
        "message" => "[2019-06-22T19:53:26.44][sio_demo_irq4_logstash.c][35]Tout = 23",
     "sourceFile" => "sio_demo_irq4_logstash.c"
}
{
       "command" => "cat /dev/ttyUSB1",
     "localTime" => "2019-06-22T19:53:26.33",
          "host" => "icequeen",
       "anyText" => "raw ADC value: 49",
      "@version" => "1",
    "@timestamp" => 2019-06-22T17:53:36.539Z,
    "sourceLine" => "35",
       "message" => "[2019-06-22T19:53:26.33][sio_demo_irq4_logstash.c][35]raw ADC value: 49",
    "sourceFile" => "sio_demo_irq4_logstash.c"
}


Widać, że raz jest to zwykły log aplikacji i wypisanie surowej wartości z konwertera A/C a innym razem (na zmianę) to wyliczona wartość temperatury w formie `Tout = xx`. Parser grok obrabia nadesłaną linijkę tak czy inaczej, ale potem filtr mutate sprawdza, czy zdarzenie zawiera informacje o temperaturze, jeżeli tak - dokonuje jej ekstrakcji (split, nowe pole outDoorTemp, konwersja na integer). Oczywiście, aby nie robić z indeksu ca80daq śmietniczki usuwane są informacje o nazwie pliku źródłowego i bieżącej linijce kodu oraz dodawany jest specjalny znacznik pozwalający sekcji out odseparować strumienie. W rzeczonej sekcji wyjściowej mamy prosty warunek - prawo/lewo i otrzymujemy w miarę typowy log aplikacyjny oraz zestaw wartości temperatury w dziedzinie czasu.

Pierwsze próby analizy zebranych danych (tu z Meratronika) wyglądały nieco pokracznie, ale wykazały sensowność dalszego drążenia tematu:

70_pierwsze.png


Aktywność strumieni danych z Meratronika i CA80 prezentuje się dobrze na domyślnym widoku Kibany - polecenie discovery:

90_logs.png


No i oczywiście najfajniejsze - wszelkiej maści wykresy i statystyki, które możemy opracowywać na bazie już zgromadzonych i ciągle napływających danych. Zauważmy, że Kibana analizuje dane z wirtualnego zbioru `*daq*`, który powstał ze złączenia (przy pomocy zapytań do Elastica) dwóch zbiorów - od CA80 i V543, to jest właśnie potęga tego ustrojstwa:

80_charts.png


Cała instalacja pracuje w czasie rzeczywistym, a automatycznie odświeżanie wykresów daje bardzo przyjemne efekty, naprawdę polecam zerknąć z oprogramowanie Elastic-a, jest doskonałe do poważnych zastosowań jak i do zwykłej, kreatywnej zabawy szczególnie jeżeli posiadamy już urządzonka potrafiące raportować jakieś fizyczne i zmienne w czasie wartości.

#slowanawiatr
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.
______________________________________________ ____ ___ __ _ _ _ _
Kończysz tworzyć dopiero, gdy umierasz. (Marina Abramović)

Awatar użytkownika
dambo
Expert
Expert
Posty: 645
Rejestracja: czwartek 17 mar 2016, 17:12

Re: [CA80][V543] Elasticsearch/Logstash/Kibana vs Meratronik V543 i CA80 - dwa światy razem.

Postautor: dambo » niedziela 23 cze 2019, 16:46

Super sprawa! Tyle technologii użytych w projekcie.

Dzięki za podzielenie się! Trzeba będzie sobie spisać te narzędzia i pobawić się nimi jak już przyjdą długie zimowe wieczory :p
Nowy blog o tematyce embedded -> https://www.embedownik.pl/

Awatar użytkownika
tasza
Geek
Geek
Posty: 1082
Rejestracja: czwartek 12 sty 2017, 10:24
Kontaktowanie:

Re: [CA80][V543] Elasticsearch/Logstash/Kibana vs Meratronik V543 i CA80 - dwa światy razem.

Postautor: tasza » niedziela 23 cze 2019, 21:30

A proszę bardzo, na zdrowie :)

♬ ☘ Moja muzyka do kodowania ♬ ♬ ♬ ☘
♫ ♩ ♪ Behemoth ⚡ ☘ ⚡ Ov Fire and the Void ♪ ♩ ♫
https://youtu.be/HCysz_0Hicg


Część instalacji z mocnym udziałem CA80 działa już prawie dobę i pracowicie chomikuje dane, ale neonowego V543 wykluczyłam z tej zabawy. Zwyczajnie, szkoda mi świecić bez sensu cudnymi Nixie. Pomiary z CA80, choć dokładnością to raczej przypominają takie ciosane siekierką są do dalszych testów zupełnie wystarczające, zarówno ilościowo jak i jakościowo.

Zacznę od erraty, ponieważ dopiero przygotowując materiał do tego posta zauważyłam śmieciowe wpisy `sourceFile` w danych strumienia ca80daq. No i faktycznie, smutkiem napawa mnie fakt, że dałam odwłoka w definicji filtru ca80.conf, wzmiankowane pole także powinno być usunięte, czyli konfiguracja poprawiona jest jak niżej:

logstash-6.5.0/ca80.conf pisze:

Kod: Zaznacz cały

input {
    pipe {
        command => "cat /dev/ttyUSB1"
    }
}
filter {
    grok { 
        match => { "message" => "\[%{TIMESTAMP_ISO8601:localTime}\]\[%{GREEDYDATA:sourceFile}\]\[%{NUMBER:sourceLine}\]%{GREEDYDATA:anyText}" }
    }
    if [anyText] =~ /Tout/ {
        mutate {
            split => ["anyText", "= "]
            add_field => { "outDoorTemp" => "%{anyText[1]}" }
        }
        mutate {       
            convert => { "outDoorTemp" => "integer" }       
            remove_field => [ "anyText" ]
            remove_field => [ "sourceLine" ]
            remove_field => [ "sourceFile" ]  # <--- to!
            add_field => { "type" => "DAQ" }
        }       
    }
}
output { 
    if [type] == "DAQ" {
        elasticsearch {
            hosts => ["localhost:9200"]
            index => ["ca80daq-%{+YYYY.MM.dd}"]
        } 
    } else {
        elasticsearch {
            hosts => ["localhost:9200"]
            index => ["ca80log-%{+YYYY.MM.dd}"]
        } 
    }
    stdout {
        codec => rubydebug
    }
}


Dane gromadzą się cały czas, webowe oprogramowanie Kibana wyłączyłam aby już nie dojeżdżać zupełnie naszego domowego komputerka, działają sobie tylko Logstash i Elasticsearch. Popatrzmy najpierw, jakimi danymi dysponujemy.

Wszelka konsolowa komunikacja z silnikiem Elastic odbywa się interfejsem REST, do dialogu z EL wystarczy znany ogólnie programik `curl`. I tak, może na początek zapytajmy silnik jakie są aktualnie dostępne indeksy i jakie mają parametry (rozmiar, ilość rekordów, etc), wywołanie:

konsola pisze:

Kod: Zaznacz cały

curl -s "http://localhost:9200/_cat/indices?v"


pokaże nam tekstową tabelkę, z której wszystkiego się dowiemy:

konsola pisze:

Kod: Zaznacz cały

health status index               uuid                   pri rep docs.count docs.deleted store.size pri.store.size
yellow open   v543daq-2019.06.19  efIPaDIkRQCoXf5gtxzSXA   5   1       2532            0    738.8kb        738.8kb
yellow open   ca80log-2019.06.23  lkwE92DyQQ2GZaB14yUDsg   5   1      53109            0     14.2mb         14.2mb
yellow open   ca80log-2019.06.22  XKesB-1bRZ6-U1d7n8JXlw   5   1      15183            0      4.3mb          4.3mb
yellow open   ca80daq-2019.06.23  f2nCgiMkQLqbHPxxcEyUDQ   5   1      53109            0     12.6mb         12.6mb
yellow open   ca80daq-2019.06.19  WcOVikLARDiSMCMXEfmIIg   5   1      21049            0      5.2mb          5.2mb
yellow open   ca80log-2019.06.19  xPh-7tEeSzWNdcxpuvs7-A   5   1      21269            0      5.9mb          5.9mb
yellow open   v543-2019.06.13     KNO4n7GcSVyjXHfhWPTRrQ   5   1        845            0    358.4kb        358.4kb
yellow open   tempdaq-2019.06.18  nj7jOAfFQ0K57Oi7oso9ww   5   1        597            0      380kb          380kb
yellow open   ca80log-2019.06.18  3dwy5R6dTYSbosmiEQuPHg   5   1        598            0    359.8kb        359.8kb
yellow open   daq-2019.06.03      tOYuO7YBTkm_q__rwHXArA   5   1         33            0    183.3kb        183.3kb
yellow open   .kibana             e7gUEb12RP2fSoRjvvWctw   1   1          9            0     51.2kb         51.2kb
yellow open   logstash-2019.05.31 _i5xq1O-TDOvuixgqR3qTQ   5   1         16            0     57.2kb         57.2kb
yellow open   ca80daq-2019.06.22  GcTKVSd9Q2-iKqyc5X1Twg   5   1      15139            0      3.8mb          3.8mb


Jak widać, dzisiejszy indeks (od północy) o nazwie `ca80daq-2019.06.23` liczy sobie ~53 tyś wpisów i zajmuje prawie trzynaście MB na dysku, No tu widać, że chomikowanie wartości temperatury co sekundę było pomysłem zaiste przednim. Ale nie ma tego złego coby na dobre - tak duży w sensie ilości rekordów wolumen danych pozwoli odczuć na własnej skórze narzut czasowy na wykonanie zapytań i analiz zbioru danych.

Na początek dowiedzmy się, w jakim zakresie czasu/dat chomikowane są dane w bieżącym (23 czerwca) indeksie:

konsola pisze:

Kod: Zaznacz cały

curl -s "http://localhost:9200/ca80daq-2019.06.23/_search" -d'
{
      "size": 0,
      "aggregations": {
      "acquisition_start": {
          "min": {
            "field": "localTime"
          }
        },
        "acquisition_end": {
          "max": {
            "field": "localTime"
          }
        }
      }
}'


Odpowiedź w postaci zrzutki ekranu, ponieważ chcę wskazać kilka upierdliwości takiego sposobu zadawania zapytań.

01_zrzut42.png


Po pierwsze, fatalnie pisze się i uruchamia dłuższe kwerendy do EL podając ich ciało jako parametr wywołania, znacznie lepiej zapakować to w plik i podstawić do curl-a. Po drugie, wynik w postaci JSON nie jest zbyt czytelny, oczywiście odcyfrujemy po dłuższym namyśle to co nas interesuje, ale wygląda to słabo. Można dodać do wywołania opcję `pretty=true`, wtedy przynajmniej JSON będzie na ekranie jakoś sformatowany, czy tak - wywołanie:

konsola pisze:

Kod: Zaznacz cały

curl -s "http://localhost:9200/ca80daq-2019.06.23/_search?pretty=true" -d @get_begin_end_acq_time.json


i okno powłoki:

02_zrzut43.png


Ładnie połamane, ale super tylko...dane jakieś dziwne, pierwszy wpis w/g zegarka CA80 dotyczył drugiej w nocy, czyli o tej godzinie EL zbudował nowy indeks. No to jest grubsza historia i walka z ustawieniami strefy czasowej tego całego stosu, nieco info na ichnim forum: :arrow: https://discuss.elastic.co/t/kibana-add ... p/63731/19

Kolejna sprawa, chcieliśmy przecież tylko dwie daty, a tu EL dostał ataku wylewności i wypisał wiele chwilowo zbędnych nam rzeczy, co z tym zrobić? No oczywiście grep+sed, ale może warto zerknąć na przesympatyczne konsolowe narządko `jq`, taki jakby sed ale do danych w JSON. Kryteria wyszukania i przetwarzania JSON-owych danych podaje się w wywołaniu, efekt jest całkiem przyjemny dla oka. Oczywiście reguły przetwarzania (filtr) możemy zapodać z pliku i całe wywołanie jest krótkie i konkretne:

konsola pisze:

Kod: Zaznacz cały

curl -s "http://localhost:9200/ca80daq-2019.06.23/_search?pretty=true" -d @get_begin_end_acq_time.json | jq -f extract_start_stop.json


extract_start_stop.json pisze:

Kod: Zaznacz cały

{
    start: .aggregations.acquisition_start.value_as_string,
    stop:  .aggregations.acquisition_end.value_as_string
}


03_zrzut44.png


Możliwości jq są naprawdę spore i uważam, że warto rozważyć jego wykorzystanie do obróbki restowych danych, ale to już jak kto lubi.

Naturalnym pytaniem, które pojawia się w kontekście takiej ilości pracowicie uciułanych danych o temperaturze jest - jaka była jej minimalna i maksymalna wartość. I kiedy? Powtarzam asekurancko, mój MCP9700 jest na parapecie od południowej strony, przy oknie nie ma przewiewu jest więc mówiąc wprost patelnia, zaraz to zobaczymy.

Pytanko o minimalną i maksymalną wartość T będzie tym razem nie do konkretnego indeksu ale do całego ich zestawu, w końcu po coś te dane historyczne zbieramy, nazwa indeksu via maska, a zapytanko takie:

konsola pisze:

Kod: Zaznacz cały

curl -s "http://localhost:9200/ca80daq*/_search?pretty=true" -d @get_min_max_T_values.json


get_min_max_T_values.json pisze:

Kod: Zaznacz cały

{
      "size": 0,
      "aggregations": {
      "min_T": {
          "min": {
            "field": "outDoorTemp"
          }
        },
        "max_T": {
          "max": {
            "field": "outDoorTemp"
          }
        }
      }
}


no i rezultat:

konsola pisze:

Kod: Zaznacz cały

{
  "took" : 10,
  "timed_out" : false,
  "_shards" : {
    "total" : 15,
    "successful" : 15,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 91895,
    "max_score" : 0.0,
    "hits" : [ ]
  },
  "aggregations" : {
    "max_T" : {
      "value" : 71.0
    },
    "min_T" : {
      "value" : 15.0
    }
  }
}


No chłodek poranny jest jak widać na poziomie, ale te 71`C to już robi wrażenie. Drobną wadą powyższego rezultatu jest to, że nie wiadomo kiedy te maksymalne i minimalne temperatury miały miejsce, zmieniamy zatem podejście, ponieważ musimy oprócz T wydłubać także znacznik czasu. I tu uwaga - nie można do tego wykorzystać funkcji agregujących min/max z prozaicznego powodu - przecież możemy mieć w dziedzinie czasu kilka jednakowych ekstremów, jakiż wtedy czas zwrócić?

Nowe zapytanko i wykorzystanie agregacji top_hits przy jednoczesnym ograniczeniu wyniku do jednej sztuki każdego.

konsola pisze:

Kod: Zaznacz cały

curl -s "http://localhost:9200/ca80daq*/_search?pretty=true" -d @get_min_max_T_values_time.json


get_min_max_T_values_time.json pisze:

Kod: Zaznacz cały

{
    "size": 0,
    "aggregations":{
        "min_temperature_events": {
            "top_hits": {
                "sort": [
                    {
                        "outDoorTemp": {
                            "order": "asc"
                        }
                    }
                ],
                "size": 1
            }
        },
        "max_temperature_events": {
            "top_hits": {
                "sort": [
                    {
                        "outDoorTemp": {
                            "order": "desc"
                        }
                    }
                ],
                "size": 1
            }
        }
       
    }
}


I wypracowany wynik:

konsola pisze:

Kod: Zaznacz cały

{
  "took" : 325,
  "timed_out" : false,
  "_shards" : {
    "total" : 15,
    "successful" : 15,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 92587,
    "max_score" : 0.0,
    "hits" : [ ]
  },
  "aggregations" : {
    "max_temperature_events" : {
      "hits" : {
        "total" : 92587,
        "max_score" : null,
        "hits" : [
          {
            "_index" : "ca80daq-2019.06.23",
            "_type" : "DAQ",
            "_id" : "AWuEOVOPfRq3jnZQ2XN3",
            "_score" : null,
            "_source" : {
              "message" : "[2019-06-23T14:04:07.52][sio_demo_irq4_logstash.c][35]Tout = 71",
              "@timestamp" : "2019-06-23T12:04:37.802Z",
              "sourceFile" : "sio_demo_irq4_logstash.c",
              "localTime" : "2019-06-23T14:04:07.52",
              "type" : "DAQ",
              "command" : "cat /dev/ttyUSB1",
              "@version" : "1",
              "host" : "icequeen",
              "outDoorTemp" : 71
            },
            "sort" : [
              71
            ]
          }
        ]
      }
    },
    "min_temperature_events" : {
      "hits" : {
        "total" : 92587,
        "max_score" : null,
        "hits" : [
          {
            "_index" : "ca80daq-2019.06.23",
            "_type" : "DAQ",
            "_id" : "AWuCHSZSfRq3jnZQ2Iu6",
            "_score" : null,
            "_source" : {
              "message" : "[2019-06-23T04:13:39.78][sio_demo_irq4_logstash.c][35]Tout = 15",
              "@timestamp" : "2019-06-23T02:14:36.779Z",
              "sourceFile" : "sio_demo_irq4_logstash.c",
              "localTime" : "2019-06-23T04:13:39.78",
              "type" : "DAQ",
              "command" : "cat /dev/ttyUSB1",
              "@version" : "1",
              "host" : "icequeen",
              "outDoorTemp" : 15
            },
            "sort" : [
              15
            ]
          }
        ]
      }
    }
  }
}


Widzimy, że EL ponownie dostał słowotoku, zatem interesujące nas dane odcedzimy sobie dodatkowym mini-filtrem jq:

konsola pisze:

Kod: Zaznacz cały

curl -s "http://localhost:9200/ca80daq*/_search?pretty=true" -d @get_min_max_T_values_time.json | jq -f extract_min_max_time.json


extract_min_max_time.json pisze:

Kod: Zaznacz cały

{
    min_temp: {
        date: .aggregations.min_temperature_events.hits.hits[0]._source.localTime,
        value: .aggregations.min_temperature_events.hits.hits[0]._source.outDoorTemp
    },
    max_temp: {
        date: .aggregations.max_temperature_events.hits.hits[0]._source.localTime,
        value: .aggregations.max_temperature_events.hits.hits[0]._source.outDoorTemp
    }
}


No i oczekiwane wyjście na konsolę:

konsola pisze:

Kod: Zaznacz cały

{
  "max_temp": {
    "value": 71,
    "date": "2019-06-23T14:04:07.52"
  },
  "min_temp": {
    "value": 15,
    "date": "2019-06-23T04:13:39.78"
  }
}


Na zakończenie, garstka linków dla ciekawskich:

:arrow: https://elasticsearch-cheatsheet.jolicode.com/
:arrow: https://medium.com/tech-feed/a-simple-e ... 975ea4a038

:arrow: https://stedolan.github.io/jq/manual/
:arrow: https://remysharp.com/drafts/jq-recipes

--edytka--
min z max zamienione

#slowanawiatr
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.
______________________________________________ ____ ___ __ _ _ _ _
Kończysz tworzyć dopiero, gdy umierasz. (Marina Abramović)

Awatar użytkownika
tasza
Geek
Geek
Posty: 1082
Rejestracja: czwartek 12 sty 2017, 10:24
Kontaktowanie:

Re: [CA80][V543] Elasticsearch/Logstash/Kibana vs Meratronik V543 i CA80 - dwa światy razem.

Postautor: tasza » wtorek 25 cze 2019, 18:37

♬ ☘ Moja muzyka do kodowania ♬ ♬ ♬ ☘
♫ ♩ ♪ Behemoth ⚡ ☘ ⚡ Bartzabel ♪ ♩ ♫
https://youtu.be/Dhfy9TPga-c


Wspominałam, że pracuje z dość starą (jak na tak wielką dynamikę rozwoju) wersją stosu ELK - 5.6, ale to w sumie dobrze się złożyło. Chęć pokazania na żywo Kibany w wersji 7.1 wymusiła konieczność migracji danych na nowszy Elasticsearch (także 7.1). Ciekawostka z cyklu multi-kulti - przeniesienie danych było nie tylko pomiędzy wersjami oprogramowania ale i systemami operacyjnymi. No niestety, filmik z Kibaną 7.1 zrobiłam na służbowej maszynie z 64-bit Win7 przy pomocy jakiegoś shareware do nagrywania gameplay z Minecraft, które to podpowiedziała mi Blondi. Bateria szybko w laptopie padła i zakończyła to windowsowe przedstawienie, ale zanim...

migracja danych Elastic-Elastic

Żywotne dla prezentacji dane zgromadzone zostały w indeksach `ca80daq-*`, dla wprawy postanowiłam przenieść nie tylko zestaw z 23 czerwca, ale 22 i 24 także.

Polecenie do Easticsearch, które należy uruchomić w kontekście docelowego EL wygląda następująco:

copy-23.json pisze:

Kod: Zaznacz cały

{
  "source": {
    "remote": {
      "host": "http://192.168.1.3:9200"
    },
    "index": "ca80daq-2019.06.23",
    "query": {
      "match_all": {}
    }
  },
  "dest": {
    "index": "ca80daq-2019.06.23"
  }
}


Sekcja `source` wskazuje na źródłowy EL, nazwę indeksu oraz ewentualne kryteria ograniczające zwracany rezultat. Sekcja `dest` sprowadza się do ustalenia docelowej nazwy indeksu odbiorczego. Wywołanie interfejsem REST sprowadza się do uruchomienia curl z takimi na przykład parametrami:

copy-23.json pisze:

Kod: Zaznacz cały

curl -s -H "Content-Type: application/json" -XPOST "http://192.168.1.8:9200/_reindex" -d @copy-23.json


Podajemy URL do naszego docelowego EL i jako parametr - plik z jsonkiem. Ważna jedna sprawa - nowsze wersje (a przynajmniej 7+) wymagają podania explicite typu danych posyłanych via HTTP, stąd opcja -H i ustalenie wartości Content-type w nagłówku HTTP, bez tego nie ruszy i trzeba pamiętać o tym drobiazgu, inaczej dostaniemy

EL pisze:{"error":"Content-Type header [application/x-www-form-urlencoded] is not supported","status":406}


Oczywiście jeżeli mamy na nowym, docelowym EL włączone zabezpieczenia (xpack.security.enabled : true) to w wywołaniu curl-a potrzeba dodać parametr `-u użytkownik:hasło` lub klucze pub/priv, aby w ogóle z silnikiem EL się skomunikować.

Radosna próba odpalenia takiej migracji danych zakończy się tym, że docelowy EL napisze - reindex? WTF? żegnam!
Cytat z windowsowej konsolki:

cmd.exe pisze:

Kod: Zaznacz cały

D:\ELK>curl -s -H "Content-Type: application/json" -XPOST "http://192.168.1.8:9200/_reindex" -d @copy-23.json
{"error":{"root_cause":[{"type":"illegal_argument_exception","reason":"[192.168.1.3:9200] not whitelisted in reindex.remote.whitelist"}],"type":"illegal_argumen
t_exception","reason":"[192.168.1.3:9200] not whitelisted in reindex.remote.whitelist"},"status":400}


I poniekąd słusznie - zbudowanie nowego indeksu na podstawie zewnętrznego źródła jest objęte restrykcjami, choćby na to, że owe źródło musi być docelowemu EL znane, robimy to w formie white-list. Należy w elasticsearch.yml docelowego EL dodać wpis rejestrujący EL źródłowy:

elasticsearch.yml pisze:

Kod: Zaznacz cały

reindex.remote.whitelist: '192.168.1.3:9200'


i cała operacja powiedzie się bez problemu. Kolejne wywołania migracji indeksów, za 22,23 i 24 czerwca:

cmd.exe pisze:

Kod: Zaznacz cały

D:\ELK>curl -s -H "Content-Type: application/json" -XPOST "http://192.168.1.8:9200/_reindex" -d @copy-22.json
{"took":4623,"timed_out":false,"total":15139,"updated":0,"created":15139,"deleted":0,"batches":16,"version_conflicts":0,"noops":0,"retries":{"bulk":0,"search":0
},"throttled_millis":0,"requests_per_second":-1.0,"throttled_until_millis":0,"failures":[]}
D:\ELK>curl -s -H "Content-Type: application/json" -XPOST "http://192.168.1.8:9200/_reindex" -d @copy-23.json
{"took":18464,"timed_out":false,"total":72319,"updated":0,"created":72319,"deleted":0,"batches":73,"version_conflicts":0,"noops":0,"retries":{"bulk":0,"search":
0},"throttled_millis":0,"requests_per_second":-1.0,"throttled_until_millis":0,"failures":[]}
D:\ELK>curl -s -H "Content-Type: application/json" -XPOST "http://192.168.1.8:9200/_reindex" -d @copy-24.json
{"took":3255,"timed_out":false,"total":12615,"updated":0,"created":12615,"deleted":0,"batches":13,"version_conflicts":0,"noops":0,"retries":{"bulk":0,"search":0
},"throttled_millis":0,"requests_per_second":-1.0,"throttled_until_millis":0,"failures":[]}
D:\ELK>


Na konsoli tekstowej docelowego Elastica widać było pracowite budowanie kolejnych indeksów:

cmd.exe - bin\elasticsearch pisze:

Kod: Zaznacz cały

[2019-06-24T20:23:00,076][INFO ][o.e.c.m.MetaDataCreateIndexService] [node-1] [ca80log-2019.06.23] creating index, cause [auto(bulk api)], templates [], shards
[1]/[1], mappings []
[2019-06-24T20:23:00,232][INFO ][o.e.c.m.MetaDataMappingService] [node-1] [ca80log-2019.06.23/ZbAamfQHQcC2tRgtuBoxaA] create_mapping [_doc]
[2019-06-24T20:29:39,109][INFO ][o.e.c.m.MetaDataCreateIndexService] [node-1] [ca80daq-2019.06.22] creating index, cause [auto(bulk api)], templates [], shards
[1]/[1], mappings []
[2019-06-24T20:29:39,249][INFO ][o.e.c.m.MetaDataMappingService] [node-1] [ca80daq-2019.06.22/FSe-O2v9SGy2q5Io2fd9gg] create_mapping [_doc]
[2019-06-24T20:29:43,758][INFO ][o.e.c.m.MetaDataCreateIndexService] [node-1] [ca80daq-2019.06.23] creating index, cause [auto(bulk api)], templates [], shards
[1]/[1], mappings []
[2019-06-24T20:29:43,882][INFO ][o.e.c.m.MetaDataMappingService] [node-1] [ca80daq-2019.06.23/NDcuF9ocQ16nTrlMdQLw-w] create_mapping [_doc]
[2019-06-24T20:30:02,306][INFO ][o.e.c.m.MetaDataCreateIndexService] [node-1] [ca80daq-2019.06.24] creating index, cause [auto(bulk api)], templates [], shards
[1]/[1], mappings []
[2019-06-24T20:30:02,431][INFO ][o.e.c.m.MetaDataMappingService] [node-1] [ca80daq-2019.06.24/r2E6YTLwS-66jHY1r6WAmQ] create_mapping [_doc]


Po zakończeniu pompowania danych (kilkanaście sekund), można było nowego (7.1) EL zapytać o listę indeksów:

cmd.exe pisze:

Kod: Zaznacz cały

D:\ELK>curl -s "http://192.168.1.8:9200/_cat/indices?v"
health status index                           uuid                   pri rep docs.count docs.deleted store.size pri.store.size
yellow open   ca80log-2019.06.23              ZbAamfQHQcC2tRgtuBoxaA   1   1      72319            0     15.2mb         15.2mb
green  open   .monitoring-es-7-2019.06.19     EUnryXP5TbGMS-QfwQMb1g   1   0       6885         5336      3.7mb          3.7mb
yellow open   ca80daq-2019.06.24              r2E6YTLwS-66jHY1r6WAmQ   1   1      12615            0      2.4mb          2.4mb
yellow open   kibana-2019.06.14               JpH_vNkpRVSlI1QYmjs7Bw   1   1          2            0       10kb           10kb
green  open   .monitoring-kibana-7-2019.06.14 X5Iaet3ZTsKFl5w0Gu8IIA   1   0        279            0    202.2kb        202.2kb
yellow open   ca80daq-2019.06.23              NDcuF9ocQ16nTrlMdQLw-w   1   1      72319            0     13.8mb         13.8mb
green  open   .monitoring-es-7-2019.06.13     swyjbM6GT5mn1790lSxM5w   1   0       4039         1584      2.4mb          2.4mb
green  open   .kibana_1                       6_3GQGwvQ8ing_mg9D59bA   1   0          6            0     30.1kb         30.1kb
green  open   .monitoring-es-7-2019.06.24     pso1vDooRj-Pt7j7Qox5IA   1   0       4330          919      4.5mb          4.5mb
yellow open   ca80daq-2019.06.22              FSe-O2v9SGy2q5Io2fd9gg   1   1      15139            0      2.8mb          2.8mb
green  open   .kibana_task_manager            N1fVWNcYSpaRreKmHQeW1g   1   0          2            0     12.7kb         12.7kb
green  open   kibana_sample_data_flights      NbVpnYQtSSaN41PPwCC5xg   1   0      12500            0      6.2mb          6.2mb
green  open   .monitoring-es-7-2019.06.14     osbmCfBISTycoKYSgDHJxQ   1   0       3534         2364      2.5mb          2.5mb
green  open   .monitoring-kibana-7-2019.06.13 VN0zzqJKRTOcaJ7g3Oeixg   1   0        275            0    123.7kb        123.7kb
green  open   .monitoring-kibana-7-2019.06.19 XAKaUL60TBqtMQqHKeGNew   1   0        177            0    126.6kb        126.6kb
green  open   .security-7                     PhY35RLARRqpw7xWwAitHA   1   0         14            0       39kb           39kb


Jak widać, sztuczka się udała i obaj pacjenci zadowoleni. Filmik poniżej to takie krótkie click-through po Kibanie, pokazuje na żywo jak fajnie można nawigować po zgromadzonych danych (wyszukanie tych min 15`C i max 71`C) oraz jak na szybko zrobić sobie wizualizację wartości w dziedzinie czasu, czyli prosty wykresik, to dosłownie chwila.

https://youtu.be/BOiRJ12LneI

#slowanawiatr
______________________________________________ ____ ___ __ _ _ _ _
Kończysz tworzyć dopiero, gdy umierasz. (Marina Abramović)

Awatar użytkownika
gaweł
Geek
Geek
Posty: 1259
Rejestracja: wtorek 24 sty 2017, 22:05
Lokalizacja: Białystok

Re: [CA80][V543] Elasticsearch/Logstash/Kibana vs Meratronik V543 i CA80 - dwa światy razem.

Postautor: gaweł » piątek 28 cze 2019, 00:16

tasza pisze:Zacznę od erraty, ponieważ dopiero przygotowując materiał do tego posta zauważyłam śmieciowe wpisy `sourceFile` w danych strumienia ca80daq. No i faktycznie, smutkiem napawa mnie fakt, że dałam odwłoka w definicji filtru ca80.conf,

Nie mylą się jedynie ci, co nic nie robią.


Faktycznie, bardzo interesujący narządź. Nie spodziewałem się tak dużej funkcjonalności. Wiesz, nawet zaczyna mi świtać pewna myśl, gdzie coś takiego będzie przydatne. Temat może być dosyć złożony i wymagający czasu na dokładniejsze przemyślenia. Na razie to gubię się w podążaniu za twoim tokiem. Bardzo mnie zainteresowałaś, będę coś kombinował w tą stronę. Jeżeli będę miał problemy, to mogę liczyć na twoje wsparcie? Oczywiście nie teraz, za jakiś czas.

Prawdziwe słowa nie są przyjemne. Przyjemne słowa nie są prawdziwe.
Lao Tse

Awatar użytkownika
xor
User
User
Posty: 169
Rejestracja: poniedziałek 05 wrz 2016, 21:44

Re: [CA80][V543] Elasticsearch/Logstash/Kibana vs Meratronik V543 i CA80 - dwa światy razem.

Postautor: xor » piątek 28 cze 2019, 12:13

To

Kod: Zaznacz cały

ssh -i ~/.ssh/otoja-dev pi@v543 'ls -l'

można sobie dalej uprościć tworząc plik ~/.ssh/config z mniej więcej takim wpisem

Kod: Zaznacz cały

Host tralala
    User pi
    HostName v543
    IdentityFile ~/.ssh/otoja-dev

Uprawnienia do pliku obowiązkowo

Kod: Zaznacz cały

rw-------

I wtedy:

Kod: Zaznacz cały

ssh tralala 'ls -l'

Awatar użytkownika
tasza
Geek
Geek
Posty: 1082
Rejestracja: czwartek 12 sty 2017, 10:24
Kontaktowanie:

Re: [CA80][V543] Elasticsearch/Logstash/Kibana vs Meratronik V543 i CA80 - dwa światy razem.

Postautor: tasza » niedziela 30 cze 2019, 19:01

@xor
za podpowiedź o ssh podziękowała, rzeczywiście ułatwienie to spore, super!

@gaweł
opisywany w EdW system Infinity (moim zdaniem) aż prosi się o integrację z tego typu narzędziem, odnośnie tego co jest, to zmiana niewielka - niech płyta z ARM robi to, co umie najlepiej - zarządza po RS485 tym całym stadem obiektowych modułków, a od strony sieci - niech ma dobrze zdefiniowany i przemyślany interface HTTP/REST, którym będzie można pytać o stan systemu lub na niego wpływać, myślę, że to jest do zrobienia.

Problemy będziesz miał, to oprogramowanie szybko ewoluuje (i niestety w nie zawsze wygodnym dla końcowego odbiorcy kierunku), ale cała w tym frajda - jednak potworka jakoś okiełznać. Pytania i porady jak najbardziej, jak będę wiedziała (ewentualnie dopytam w fabryce) to odpiszę, może coś się jednak zadzieje na forum, poza czatem.

ps.
aktualnie obczaiłam, jak wstawiać do Elasticsearch dane bezpośrednio z LabVIEW, tak na krótko, z pominięciem Logstash, tak więc Analog Discovery 2 skwierczy mi na balkonie (a ja obok) i twardo wrzuca te swoje pomiarowe zdarzenia, o tym w kolejnym poście.
______________________________________________ ____ ___ __ _ _ _ _
Kończysz tworzyć dopiero, gdy umierasz. (Marina Abramović)

Awatar użytkownika
gaweł
Geek
Geek
Posty: 1259
Rejestracja: wtorek 24 sty 2017, 22:05
Lokalizacja: Białystok

Re: [CA80][V543] Elasticsearch/Logstash/Kibana vs Meratronik V543 i CA80 - dwa światy razem.

Postautor: gaweł » poniedziałek 01 lip 2019, 15:00

tasza pisze:Problemy będziesz miał, to oprogramowanie szybko ewoluuje (i niestety w nie zawsze wygodnym dla końcowego odbiorcy kierunku), ale cała w tym frajda - jednak potworka jakoś okiełznać. Pytania i porady jak najbardziej, jak będę wiedziała (ewentualnie dopytam w fabryce) to odpiszę, może coś się jednak zadzieje na forum, poza czatem.

Dziękuję ci serdecznie. Co do problemów, to powoli do nich przywykłem, ale po to są problemy by je rozwiązywać a nie unikać. Ja cały czas nad tym kombinuję. Jakby ci tu powiedzieć... łatwo nie jest, ale jestem dobrej myśli. To nie może się nie udać, ale nie teraz, jeszcze nie jestem gotów.

Prawdziwe słowa nie są przyjemne. Przyjemne słowa nie są prawdziwe.
Lao Tse

Awatar użytkownika
PROTON
Expert
Expert
Posty: 527
Rejestracja: czwartek 08 paź 2015, 18:35
Lokalizacja: Warszawa

Re: [CA80][V543] Elasticsearch/Logstash/Kibana vs Meratronik V543 i CA80 - dwa światy razem.

Postautor: PROTON » poniedziałek 01 lip 2019, 19:44

Fajnie że używasz ELK Stack, sam to stosuję od lat.
Zawsze były problemy przy migracji danych do nowszej wersji oprogramowania, do tego sporo metod też się zmienia, cały czas trzeba dostosowywać oprogramowanie.
Dodam od siebie coś na temat ELK Stack:
W zestawie jest jeszcze program Filebeat, umożliwia czytanie plików logów które na bieżąco są aktualizowane i przesyłanie ich po sieci do Logstasha.
Logstash jest w stanie parsować logi wielolnijkowe, np. zrzut nagłówka POST HTTP i wyciągnąć z niego wszelkie informacje.
Elasticsearch świetnie się skaluje na wiele serwerów podnosząc wydajność, na jednym mocnym serwerze (20c CPU, 256GB RAM) dopiero przekroczenie 500 000 000 rekordów daje mocne spowolnienie. Bardzo dobrze działa w kontenerze Docker.
Jest dobra biblioteka do Pythona, głównie jej używam do pracy z Elasticsearch, wszelkie naprawy, migracje danych, itp.
Programy piszę tak aby bezpośrednio pisały do Elasticsearch, wystarczy przygotować jsona i go wrzucić po HTTP.
Jeśli logów jest dużo, można wrzucać je w trybie _bulk, przygotowuje się jednego jsona, który możne zawierać kilkaset linii logów i za pomocą jednego wywołania HTTP pakuje się całą zawartość do bazy.
Gott weiß ich will kein Engel sein.


Wróć do „Retro”

Kto jest online

Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 4 gości