Für Last-Analysen, Performance-Analysen und Robustheitsanalysen ist es sinnvoll die CPU Auslastung des Zielsystems zu kennen um auf mögliche Ressourcenprobleme bei des CPU zu schliessen. Dabei sind die Programme top und stop die ersten Anlaufpunkte. Um aber die gesamte CPU Auslastung automatisch per BASH Script zu erfassen sind nur begrenzt geeignet. Alternativ kann man sysstat benutzen, welches aber erst installiert werden muss. Hier nun eine sehr einfache Methode die CPU Auslastung per BASH Script ohne Zusatzsoftware zu erfassen:
ps -A -o pcpu | tail -n+2 | paste -s -d '+' - | tr , . |bc
Dieser Wert muss dann noch durch die Anzahl der CPUs geteilt werden um die Auslastung des Servers zu ermitteln. Das tr ist nur auf Systemen notwendig, die ein Komma als Dezimal-Separator haben, sonst schadet es aber auch nicht.
Die Anzahl der Kerne eines Servers kann man auf verschiedene Weisen ermitteln. Hier die meine, welche für Linux als auch für macOS funktioniert:
getCores () {
os=`uname`
if [[ "$os" == 'Linux' ]]; then
core=`nproc`
elif [[ "$os" == 'Darwin' ]]; then
core=`sysctl -n hw.ncpu`
else
echo "Error: Unsupported platform: $os"
core=-1
exit
fi
}
Die Anzahl der Kerne wird in die BASH Variable $core geschrieben.
Mittwoch, 12. Oktober 2016
Mittwoch, 5. Oktober 2016
Schnell Analysen mit R: Ich kenn SQL aber wie mache ich das in R?
Hier eine kleine Anleitung für SQL erfahrene Benutzer um Daten schnell und effizient mit R zu analysieren.
Mit R kann ohne Zusatzpakete jedes Problem lösen. Leider sind einige Funktionen in R relativ umständlich und bei grossen Datenmengen nicht sehr performant. Ein R-Paket mit dem es schneller und einfacher geht ist: data.table. Alternativ können auch andere Pakete wie dplyr oder sqldf benutzt werden. Dplyr setzt auf Pipes (wie Splunk auch) zur Verarbeitung der Daten. Mit dem R-Paket sqldf werden die Daten in eine SQLite Datenbank übertragen. Dann können die Daten einfach mit SQL abgefragt werden: sqldf("select avg(vctotal), avg(dctotal) from a2 where label ='A'"). Hier noch eine Anmerkung zur Benutzung von Date Feldern in sqldf, die Date Strings müssen ins UTC ticks / unix epoch Werte umgerechnet werden. Das ist das interne Format der Datenbank.
Aber los gehts.
Voraussetzung:
Anmerkungen
Mit R kann ohne Zusatzpakete jedes Problem lösen. Leider sind einige Funktionen in R relativ umständlich und bei grossen Datenmengen nicht sehr performant. Ein R-Paket mit dem es schneller und einfacher geht ist: data.table. Alternativ können auch andere Pakete wie dplyr oder sqldf benutzt werden. Dplyr setzt auf Pipes (wie Splunk auch) zur Verarbeitung der Daten. Mit dem R-Paket sqldf werden die Daten in eine SQLite Datenbank übertragen. Dann können die Daten einfach mit SQL abgefragt werden: sqldf("select avg(vctotal), avg(dctotal) from a2 where label ='A'"). Hier noch eine Anmerkung zur Benutzung von Date Feldern in sqldf, die Date Strings müssen ins UTC ticks / unix epoch Werte umgerechnet werden. Das ist das interne Format der Datenbank.
Aber los gehts.
Voraussetzung:
- data.table geladen
- Daten aus CSV Datei in die Variable g geladen.
Anmerkungen
- Row (R) und Tupel (SQL) werden hier synonym verwand.
- Was in Programmiersprachen wie Java der Punkt ist ist in R das $ Zeichen.
- Mit installiertem OpenMP laufen einige data.table Operationen schneller. Auf dem Mac installiert man OpenMP mit brew install openmpi
- Effiziente Benutzung von data.table Link
R data.table cheat sheet
Aufgabe
|
SQL
|
R + data.table
|
Anmerkung
|
|---|---|---|---|
| Auswahl mit Hilfe eines Vergleichs Rows/Tupel | select * from g where dc < 10000 | g[ dc < 10000, ] | Nicht das Komma vergessen |
| Nur die ersten 15 Rows anzeigen | select * from g limit 15 |
head( g, 15)
g[ 1:15, ]
| Beide Varianten gehen |
| Mehrfach Auswahl | select * from g where dc < 10000 and dc > 500 | g[ dc < 10000 & dc > 500, ] | |
| Zählen der Ergebnisse | select count(*) from g | g[ , .N ] |
.N ist eine spezielle Variable in data.table - alternativ kann man die Anzahl auch über dim(g)[1] bestimmen.
|
| Mittelwert berechnen | select avg(dc) from g | g[ , mean(dc) ] | In R heisst der Mittelwert mean und nicht average |
| Mittelwert und Median berechnen | ??? | g[ , c(mean(dc), median(dc)) ] | Hier müssen die Berechnungen mittel c() zusammengefasst werden |
| Mittelwert berechnen bezogen auf verschiedene Gruppen | select avg(dc) from g grouped by AB | g[ , mean(dc), by = AB ] | Achte auf das = nach dem by |
| Auswahl mit einer Liste |
select * from where visit IN (values)
| a[ a$visit %in% meineListe ] | wichtig sind hier die umschliessenden % Zeichen, meineListe ist eine Liste mit den Selektionierten - values sind die Werte selbst |
| Umgekehrte Auswahl mit einer Liste | select * from where visit NOT IN (values) | a[ !(a$visit %in% meineListe) ] | Negation mit ! |
| Vorkommen von Werten zählen | select count(*) from g grouped by visit | table( g$visit ) | um teure Operationen zu testen, kann man die Operation auf einem Subset durchführen table( g[1:50]$visit ) |
| Left outer join | select * from g, t | g[ t ] |
Anmerkung: es müssen in g und t die Spalten als Key gesetzt werden die man für den Join benutzen möchte
setkey(g, visit)
setkey(t, visit)
|
| Berechnen einer neuen Spalte | ALTER TABLE g ADD vkok AS (vc<10000 & vc>500) | a1[ , vkok:=(vc < 10000 & vc > 500) ] | Hier wird in Place eine neue Spalte mit boolschen Werten berechnet: vkok |
| Löschen einer Spalte | ALTER TABLE c DROP COLUMN vcgroup | g$vcgroup = NULL | |
| Teilen ein Menge in gleich grosse Teilmengen (Buckets) | g1$vcg = as.numeric( cut2( g1$vc, g = 5) ) | Es wird eine neue Spalte den Daten hinzugefügt die die Gruppennummer des Buckets enthält. Die Buckets enthalten gleich viele Element, dies kann wie folgt geprüft werden: g1[, .N , by = vcg] Die Buckets werden entlang der Dimension vc gebildet. Aufsummiert ergeben die Buckets eine Percentil-Zerlegung der Daten. | |
| Auswahl einer Menge Mittels Like | SELECT * FROM a1 WHERE url LIKE "amount.json" | a1[ like(url,"amount.json") ] | Die LIKE Funktion ist eine Art sehr einfacher Grep |
| Sortieren | SELECT * FROM a1 ORDER BY ttfb ASC | a1[ order(ttfb) ] | Sortiert das Ergebnis der Abfrage nach dem Feld ttfb. Es können auch mehrere Felder angegeben werden, nach denen sortiert wird. Wichtig, hier keine Anführungszeichen beim Feldnamen (colname) verwenden. |
| Sortieren | SELECT * FROM a1 ORDER BY ttfb DSC | a1[ order(-ttfb) ] | Sortiert das Ergebnis der Abfrage nach dem Feld ttfb in der engegengesetzten Reihenfolge (absteigend). |
Mittwoch, 14. September 2016
Robust Code: Update von Daten mittels Switch
Stell dir vor du downloadest regelmäßig eine Datei, die du danach weiter verarbeitest. Hier zur Illustration als Bash:
curl -sS "http://eber-p.com/report.csv" | wc -l
Wenn jetzt der Download aus irgend einem Grund fehlschlägt, dann bricht die Datenverarbeitung ab. Dein Service liefert keine Ergebnis mehr. Hier pflanzt sich ein Fehler durch mehrere Systeme fort. Das kann gewollt sein, meistens möchte man aber eine robuste Lösung die nicht bei jedem Downloadfehler zusammenbricht. Dies kann man erreichen, in dem man die alte Datei nicht überschreibt, sondern als Fall Back behält und sie ggf. erst nach einem erfolgreichen Download überschreibt.
wget "http://eber-p.com/report.csv"
r=`ls -t report.csv* | head -n 1`
cat $r | wc -l
Wichtig ist nur, dass man die Benutzung des Fall Backs dokumentiert, im Log File und oder in der Antwort des Services. Letztere wird hier nicht gemacht.
Kurz zusammengefasst die robuste Softwarelösung:
Zum Thema hier noch ein passender Link. Dort wird diese Problematik unter dem Begriff Be Atomic beschrieben.
Hier das ganze Beispiel-Skript:
#! /bin/sh
echo "Test with right URL"
u="http://ebert-p.com/report.csv"
echo "Non robust code"
curl -sS $u | wc -l
echo "Robust code"
wget -q -a log.log $u
r=`ls -t report.csv* | head -n 1`
cat $r | wc -l
echo "Test with wrong URL"
u="http://ebert-p.com/report_wrong.csv"
echo "Non robust code"
curl -sS $u | wc -l
echo "Robust code"
wget -q -a log.log $u
r=`ls -t report.csv* | head -n 1`
cat $r | wc -l
Und die Konsolen Ausgabe:
Test with right URL
Non robust code
1518
Robust code
1518
Test with wrong URL
Non robust code
24
Robust code
1518
curl -sS "http://eber-p.com/report.csv" | wc -l
Wenn jetzt der Download aus irgend einem Grund fehlschlägt, dann bricht die Datenverarbeitung ab. Dein Service liefert keine Ergebnis mehr. Hier pflanzt sich ein Fehler durch mehrere Systeme fort. Das kann gewollt sein, meistens möchte man aber eine robuste Lösung die nicht bei jedem Downloadfehler zusammenbricht. Dies kann man erreichen, in dem man die alte Datei nicht überschreibt, sondern als Fall Back behält und sie ggf. erst nach einem erfolgreichen Download überschreibt.
wget "http://eber-p.com/report.csv"
r=`ls -t report.csv* | head -n 1`
cat $r | wc -l
Wichtig ist nur, dass man die Benutzung des Fall Backs dokumentiert, im Log File und oder in der Antwort des Services. Letztere wird hier nicht gemacht.
Kurz zusammengefasst die robuste Softwarelösung:
- Lose Kopplung von Programmteilen die unterschiedliche Funktionen hat, hier Datenbeschaffung und Logik (hier zählen der Zeilen des Reports).
- Puffern von alten Daten und Nutzung von diesen Daten als Fallback.
Zum Thema hier noch ein passender Link. Dort wird diese Problematik unter dem Begriff Be Atomic beschrieben.
Hier das ganze Beispiel-Skript:
#! /bin/sh
echo "Test with right URL"
u="http://ebert-p.com/report.csv"
echo "Non robust code"
curl -sS $u | wc -l
echo "Robust code"
wget -q -a log.log $u
r=`ls -t report.csv* | head -n 1`
cat $r | wc -l
echo "Test with wrong URL"
u="http://ebert-p.com/report_wrong.csv"
echo "Non robust code"
curl -sS $u | wc -l
echo "Robust code"
wget -q -a log.log $u
r=`ls -t report.csv* | head -n 1`
cat $r | wc -l
Und die Konsolen Ausgabe:
Test with right URL
Non robust code
1518
Robust code
1518
Test with wrong URL
Non robust code
24
Robust code
1518
Nicht-Funktionale Anforderung: Software Robustness
Robustheit ist die Toleranz gegenüber Fehlern. Robustheit gehört damit zu den nicht-funktionalen Anforderungen. Die Toleranz gegenüber Fehlern kann auf unterschiedliche Weise realisiert werden. Systeme gelten als robust, wenn sie folgende Eigenschaften hat:
Robustheit zahlt direkt auf die Verfügbarkeit von Systemen ein, sowohl was die Häufigkeit von Störungen als auch auf den zeitlichen Umfang der Störung angeht. Oder anders formuliert, robuste Softwaresysteme haben eine höhere Verfügbarkeit als weniger robuste Softwaresysteme.
Robustheit kann durch verschieden Massnahmen erreicht werden:
Alles was man nicht testet funktioniert auch nicht, so auch Software Robustheit. Deswegen muss Robustheit auch durch Robustheitstests gesichert werden.
- Ein Fehler führt nicht zum Ausfall des gesamten Systems.
- Das System kann Fehler selbst beheben oder umgehen.
- Die Auswirkung eines Fehlers bleiben lokal begrenzt, sowohl aus zeitlicher als auch aus Systemsicht.
Robustheit zahlt direkt auf die Verfügbarkeit von Systemen ein, sowohl was die Häufigkeit von Störungen als auch auf den zeitlichen Umfang der Störung angeht. Oder anders formuliert, robuste Softwaresysteme haben eine höhere Verfügbarkeit als weniger robuste Softwaresysteme.
Robustheit kann durch verschieden Massnahmen erreicht werden:
- Redundanz
- Robuste Software Architektur
- Exception Handling
- Fall Backs
- Funktionsreduktion
Alles was man nicht testet funktioniert auch nicht, so auch Software Robustheit. Deswegen muss Robustheit auch durch Robustheitstests gesichert werden.
Dienstag, 13. September 2016
Sicherheitsproblem API Token
API Token sind eine einfache Möglichkeit um den Zugriff auf z.B. Rest API zu steuern. Ein API Token ist in der Regel ein längerer String mit zufälligem Inhalt, der dem Programmierer den Zugriff auf das API erlaubt. Der Benutzer bzw. Programmierer wird identifiziert sich mittels des API Tokens. Wie Kristopher Sandoval in seinem Blog Artikel ausführt, sollten man kritisch auf die scheinbare Sicherheit der API Token schauen. Zum Umgang mit API Token hier ein paar Tipps:
- Einen API Token sollte man wie privaten SSH Key behandeln.
- Man sollten ihn auf keinen Fall innerhalb des Projektes, egal ob in einer plain Textdatei oder im Code haben.
- Im einfachsten Fall sollte man den API Token im hoffentlich gesicherten User Verzeichnis ablegen, auf dem hoffentlich verschlüsseltem Disk Volumen.
- Bei Rest APIs sollte der API Token nur per sicherem HTTPS benutzt werden.
- Der API Token sollte nie in öffentliche Code Repos wie Github gepostet werden. Das Entfernen von solchen Git Pushes ist kein Spass. Hier kann ein Git Hook (pre-commit) hilfreich sein, der den Code nach verdächtigen Strings oder Dateien durchsucht.
- Auch sollten sie nicht in Wikis abgelegt werden.
Links:
Dienstag, 30. August 2016
Docker at Digital Ocean
Start an Centos Droplet at Digital Ocean with Docker Machine:
$ docker-machine create --driver digitalocean --digitalocean-region "fra1" --digitalocean-size "1gb" --digitalocean-image "centos-7-2-x64" --digitalocean-access-token $DOTOKEN mer
Remarks:
$ docker-machine create --driver digitalocean --digitalocean-region "fra1" --digitalocean-size "1gb" --digitalocean-image "centos-7-2-x64" --digitalocean-access-token $DOTOKEN mer
Remarks:
- Update your docker installation, because a bug prevent using Centos with Docker on Cloud provider like Digital Ocean.
- Digital Ocean regions must be lower case.
- You need an API Token at Digital Ocean.
- Look at image syntax "Centos 7.2 x64" -> "centos-7-2-x64"
Sonntag, 31. Juli 2016
Tinkerforge IoT First Steps Java Project launched on Github
I launched the first steps Java project for learning Tinkerfor ge and IoT (Github).
It uses following hardware as my simple and low cost starter kit:
It uses following hardware as my simple and low cost starter kit:
- Master Brick
- Segment Display 4x7 Bricklet
- Teperature Bricklet
- Ambient Light Bricklet
- Accelerometer Prickelt
The newbie can start with some experiments or challenges:
- Hello World
- Simple Themometer
- Thermomenter and Clock
- Small weather station with temeperatur, time and illumination
- Resource saving programming with Call Backs/Listeners
- Ambient Light sensor as contactless display light switch
- Accelerometer as contactless switch
Code examples helps to realize the challenges.
Abonnieren
Posts (Atom)
