Profile cover photo
Profile photo
LinuxTweaks
17 followers -
Linux Commandline Tweaks
Linux Commandline Tweaks

17 followers
About
LinuxTweaks's posts

Post has attachment
Marc's Linux Tweak #26:

Aus aktuellem Anlaß :-)

grep "GET /Sale" /data/logs/access-foobar.com.*.log |awk '{print int($(NF-1)/1000)*1000}'|sort|uniq -c|awk '{printf("%-10s %-10s ",($2 / 1000000 ),$1); for(i=0 ; i<$1; i++ ){printf("=")};printf("\n");}'|sort -n -k 1 |awk 'BEGIN{printf("%-10s %-10s\n","sec","hits");}{print $0}'|less -n

Dieses Konstrukt erzeugt ein Histogramm inklusive grafischer Veranschaulichung der Apache-Auslieferungs Zeiten einer bestimmten Seite.

Hierfür wird aus der zweitletzten Zeile (auf vielen Webservern anders) die mit dem Format-Konstrukt "%D" (http://httpd.apache.org/docs/2.4/mod/mod_log_config.html) erfasste Zeit gelesen und diese werden dann in 1000er Quantile gruppiert. Das Ergebnis wird sortiert, die Duplikate gezählt und dann dargestellt.

Marc's Linux Tweak #25:

cat > /tmp/dodump <<EOF
gcore jvm.core
detach
quit
EOF
time gdb --batch --command=/tmp/dodump --pid=`pgrep java`
jmap -dump:format=b,file=jvm.hprof `which java` jvm.core
rm jvm.core
gzip -9 jvm.hprof 


Das Erzeugen von Java Heapdumps im Fall von GC Problemen oder java.lang.OutOfMemoryError mit "jmap -heap:format=b <pid>" ist immer extrem zeitraubend und zieht die Downtime der Anwendung unnötig in die Länge.

Über den GNU Debugger lässt sich ein Speicherabbild des Prozesses mehr als 10 mal so schnell ziehen. Auf diesem Coredump kann man dann "jmap" anwenden um den eigentlichen Heapdump zu ziehen. Beispielsweise über VisualVM kann man dann den Heapdump analysieren - vorausgesetzt man hat genug Arbeitsspeicher.

Marc's Linux Tweak #24:

lsof +L1

Dieser Befehl zeigt alle Dateien eines Systems die gelöscht sind, auf die aber noch Filedeskriptoren geöffnet sind.
Der genutzte Speicherplatz einer Datei wird nach dem Löschen erst freigegeben, wenn alle Prozesse die Datei geschlossen haben.
Gibt es Abweichungen zwischen dem belegten Plattenplatz eines Dateisystems zwischen des Ausgaben von "df -h" und "du -sh <dateisystem>" liegt
das meist daran das Prozesse noch Dateien geöffnet haben.
(z.B. Java Logfiles oder die Cache-Dateien des APC)

Marc's Linux Tweak #23:

echo 'call umask(0)' >/tmp/umask.gdb
gdb --batch --command=/tmp/umask.gdb --pid=<pid>
  => Man erhält z.B. "$1 = 18"
printf "%04o" "18"
  => liefert dann die UMask "0022"

Möchte man die aktuelle UMask eines Prozesses rausfinden (beispielsweise um rauszufinden ob dieser die gesetzte Umask selbst verändert hat), kann man das wie oben beschrieben machen.

Marc's Linux Tweak #22:

---------------------------------
#!/bin/bash

stacktrace ()
{
   declare frame=0
   declare argv_offset=0
   declare indent=""

   while caller_info=( $(caller $frame) ) ; do

       if shopt -q extdebug ; then

           declare argv=()
           declare argc
           declare frame_argc

           for ((frame_argc=${BASH_ARGC[frame]},
               frame_argc--,argc=0; frame_argc >= 0; argc++,
               frame_argc--)) ; do
               argv[argc]=${BASH_ARGV[argv_offset+frame_argc]}
               case "${argv[argc]}" in
                   *[[:space:]]*) argv[argc]="'${argv[argc]}'" ;;
               esac
           done
           argv_offset=$((argv_offset + ${BASH_ARGC[frame]}))
           echo "$indent :: ${caller_info[2]}: Line ${caller_info[0]}: ${caller_info[1]}(): ${FUNCNAME[frame]}(${argv[*]})"
       fi
       indent="$indent "
       frame=$((frame+1))
   done

   if [[ $frame -eq 1 ]] ; then
       caller_info=( $(caller 0) )
       echo ":: ${caller_info[2]}: Line ${caller_info[0]}: ${caller_info[1]}"
   fi
}



foo2() {
   foo3 7 8 9
}


foo1() {
   foo2 4 5 6 
}

foo3() {
   stacktrace
}


shopt -s extdebug
foo1 1 2 3
---------------------------------

Die Bash verfügt über interessante aber auch etwas sperrige Debugging-Möglichkeiten:
Führt man das oben aufgeführte Beispielscript aus, erhält man einen Stacktrace samt aller Aufrufparameter der Funktionen sobald die Funktion foo3() ausgeführt wird.

---------------------------------
$ ./test.sh 
 :: ./test.sh: Line 48: foo3(): stacktrace()
  :: ./test.sh: Line 39: foo2(): foo3(7 8 9)
   :: ./test.sh: Line 44: foo1(): foo2(4 5 6)
    :: ./test.sh: Line 53: main(): foo1(1 2 3)
---------------------------------

Post has attachment
Marc's Linux Tweak #21:

shopt -s nullglob
for i in  /sys/block/{hd*,sd*,dasd*}; do 
   printf "DEVICE: %-5s => ROTATING : %-10s => IO-Scheduler: %s\n" `basename $i` "`cat $i/queue/rotational`" "`cat $i/queue/scheduler`"
done
shopt -u nullglob

Dieses Scriptfragment zeigt die IO-Scheduler Einstellungen der Disks die mit hd* bzw. sd* bezeichnet werden.
Spalte 1 zeigt den Devivenamen, Spalte 2 zeigt ob der Kernel der Meinung ist dass das Device eine konventionelle Festplatte ist und dann wird der gewählte IO Scheduler gezeigt.
(siehe auch http://www.thomas-krenn.com/de/wiki/Linux_I/O_Scheduler oder http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/block/switching-sched.txt?id=HEAD)
Aus der reinen Script-Sichtweise sind die beiden "shopt" Befehle interessant. Das setzen der "nullglob" Option bewirkt, dass unerfüllbare Globs nicht den Glob selbst zurückgeben, sondern dann gar nichts zurückgegeben wird. In unserem Fall vermeidet dass dann Fehlermeldungen.

Post has attachment
Marc's Linux Tweak #20:

nocache script_with_high_file_io_rate.sh

Mit ionice und nice lassen sich die Ressourcen eines Prozesses limitieren. Macht ein Prozess eine Menge File-IO
beeinflusst das den Linux-Filesystemcache und es werden so möglicherweise andere Pagecache-Einträge verdrängt.
Das beeinflusst dann aber doch die Performance anderer Prozesse.
Lösen lässt sich das mit dem Tool "nocache" (aus dem gleichnamigen Debian Paket, siehe auch https://github.com/Feh/nocache)

Marc's Linux Tweak #19:

ionice -c3 nice -n 20 resource_hungy_script.sh

Manchmal möchte man einen Cronjob oder ein Script z.B. auf einem produktiven Server so starten, das es nur die
Resourcen nutzt die das System im Moment übrig hat.
Die Kombination "ionice" und "nice" sorgt dafür das der Prozess in der Idle-IO-Scheduling-Class und in der niedrigsten
CPU Scheduling Priority läuft.

Marc's Linux Tweak #18:

cp -al foo bar

Ein Verzeichnis effizient mit Hardlinks duplizieren. Das spart Platz auf dem Filesystem und eine Menge Zeit beim Duplizieren. 
Die Verzeichniseinträge beider Verzeichnisse zeigen damit auf die selben Daten. 
Wird dann ein File dieser beiden Verzeichnisse neu geschrieben löst sich diese zweifache Referenzierung wieder auf.
Werden Daten jedoch an vorhandene Files angehängt, erfolgt die Änderung in beiden Verzeichnissen.

Marc's Linux Tweak #17:

Wie in #13 beschrieben, kann man die Ulimits bzw. RLimits eines Prozesses mit
"cat" anschauen. 

cat /proc/<pid>/limits
egrep "Limit|Max open files" /proc/<pid>/limits
echo -n "Max open files=20000:20000" > /proc/<pid>/limits
egrep "Limit|Max open files" /proc/<pid>/limits

Man man sieht, kann die Einstellungen eines laufenden Prozesses auch verändern, wenn
man das Hard- und das Softlimit mit dem Bezeichner in das "limits" File schreibt.
Wait while more posts are being loaded