FHEM Forum

FHEM - Entwicklung => Wunschliste => Thema gestartet von: Ruebezahl am 10 Juni 2014, 09:21:56

Titel: FHEM.log ins Syslog
Beitrag von: Ruebezahl am 10 Juni 2014, 09:21:56
Hallo,
da ich mehrere Server über rsyslog ihr Syslog in ein zentrales Log schreiben lasse, möchte ich auch gerne, das der Raspberry mit FHEM sein FHEM-Log in dieses zentrale Syslog schreibt. Das normale Syslog des Raspberry ist bereits über rsyslog dazu in der Lage.

Ich habe jetzt mal in die fhem.pl geschaut und gesehen (und ausprobiert), das es ja nur kleine Änderungen wären, die dazu nötig sind, das fhem-log nur noch ins Syslog zu schreiben.

ich habe dazu folgendes geändert:

......
use Time::HiRes qw(gettimeofday);
use Sys::Syslog qw(:DEFAULT setlogsock);

##################################################
# Forward declarations
......

.....
my $AttrList = "verbose:0,1,2,3,4,5 room group comment alias ".
                "eventMap userReadings";
my $syslog = 0;                  # write all messages to syslog
my $currcfgfile="";      # current config/include file
my $currlogfile;
.......



......
################################################
# the new Log with integrated loglevel checking
sub
Log3($$$)
{
  my ($dev, $loglevel, $text) = @_;

  $dev = $dev->{NAME} if(defined($dev) && ref($dev) eq "HASH");
     
  if(defined($dev) &&
     defined($attr{$dev}) &&
     defined (my $devlevel = $attr{$dev}{verbose})) {
    return if($loglevel > $devlevel);

  } else {
    return if($loglevel > $attr{global}{verbose});

  }

  my ($seconds, $microseconds) = gettimeofday();
  my @t = localtime($seconds);
  my $nfile = ResolveDateWildcards($attr{global}{logfile}, @t);
  OpenLogfile($nfile) if(!$currlogfile || $currlogfile ne $nfile);

  my $tim = sprintf("%04d.%02d.%02d %02d:%02d:%02d",
          $t[5]+1900,$t[4]+1,$t[3], $t[2],$t[1],$t[0]);
  if($attr{global}{mseclog}) {
    $tim .= sprintf(".%03d", $microseconds/1000);
  }

  if($logopened) {
    if($syslog == 1)
   {
      syslog('info',"$tim $loglevel: $text\n");
   }
   else
   {

          print LOG "$tim $loglevel: $text\n";
   }
  } else {
    print "$tim $loglevel: $text\n";
  }
  return undef;
}
.......


......
#####################################
sub
OpenLogfile($)
{
  my $param = shift;

  close(LOG);
  $logopened=0;
  $currlogfile = $param;

  # STDOUT is closed in windows services per default
  if(!$winService->{AsAService} && $currlogfile eq "-") {
    open LOG, '>&STDOUT' || die "Can't dup stdout: $!";

  } else {

    if(lc($currlogfile) eq 'syslog') {
   openlog($0,'cons,ndelay,pid,nowait','user');
   $syslog = 1;
   } else {


    HandleArchiving($defs{global}) if($defs{global}{currentlogfile});
    $defs{global}{currentlogfile} = $param;
    $defs{global}{logfile} = $attr{global}{logfile};

    open(LOG, ">>$currlogfile") || return("Can't open $currlogfile: $!");
    redirectStdinStdErr() if($init_done);
    }
  }
  LOG->autoflush(1);
  $logopened = 1;
  return undef;
}
....


Dadurch schreibt fhem nun seine Daten ins Syslog, wenn man   attr global logfile syslog    angibt.

Wäre es möglich diese Änderung dauerhaft in fhem zu implementieren, wenn damit keine anderen Probleme, die ich derzeit nicht abschätzen kann, verbunden sind???
Bei mir läuft das jetzt seit einigen Wochen ohne Probleme.

Viele Grüße,

Ruebe
Titel: Antw:FHEM.log ins Syslog
Beitrag von: betateilchen am 10 Juni 2014, 11:29:24
Zitat von: Ruebezahl am 10 Juni 2014, 09:21:56
Wäre es möglich diese Änderung dauerhaft in fhem zu implementieren, wenn damit keine anderen Probleme, die ich derzeit nicht abschätzen kann, verbunden sind?

Ich denke, das größte Problem dürfte das zusätzlich benötigte perl-Modul sein.
Titel: Antw:FHEM.log ins Syslog
Beitrag von: Ruebezahl am 10 Juni 2014, 12:02:00
Wäre es vielleicht möglich diese Funktionalität nicht in fhem.pl abzubilden, sondern in einem anderen Modul, welches erstmal das Vorhandenssein des benötigten perl-moduls prüft und dann weiter arbeitet. Da könnte man auch ggf. die Benutzer, die fhem unter Windows laufen lassen, abfangen.....

Titel: Antw:FHEM.log ins Syslog
Beitrag von: Kurd_Bahr am 03 August 2014, 21:17:53
Ich finde es auch nützlich, Events mittels syslog zu protokollieren. Solange es dafür kein eigenes Kommando bzw. Modul gibt, behelfe ich mir mit zwei "notify" Definitionen.
Die erste sorgt dafür, dass beim Start das Perl-Modul Sys::Syslog geladen wird:
define syslog_open notify global:INITIALIZED {
  use Sys::Syslog;
  openlog("fhem","ndelay","local0");
  return;
}

Das "return;" verhindert, dass der Rückgabewert von openlog im fhem.log protokolliert wird.

Das zweite "notify" erledigt die eigentliche Protokollierung aller Events:
define syslog notify  .* {
  syslog("info","$NAME: $EVENT")
    if defined &syslog;
  return;
}

Die Bedingung "if defined &syslog" vermeidet Fehlermeldungen, wenn versucht wird "syslog" aufzurufen, bevor das obige "openlog" ausgeführt wurde.

Hier nochmal für Copy & Paste ins fhem.cfg mit Backslashes und gedoppelten ";":
define syslog_open notify global:INITIALIZED { \
  use Sys::Syslog;; \
  openlog("fhem","ndelay","local0");;\
  return;;\
}
define syslog notify .* { \
  syslog("info","$NAME: $EVENT") \
    if defined &syslog;;\
  return;;\
}


Es werden hiermit jedoch nur Events protokolliert, also nicht die Fehlermeldungen, die normalerweise im fhem.log landen.
Insofern gehört das hier nicht direkt zum Thema, aber einen passenderen Thread hat mir die Suchfunktion nicht geliefert.
Titel: Antw:FHEM.log ins Syslog
Beitrag von: dindihi am 15 Mai 2015, 23:46:43
Eventuell etwas spät, jedoch hier eine nette Lösung:
Auf meinem Raspberry, wo fhem läuft, rsyslog installiert.

Dann in die /etc/rsyslog.conf:
$ModLoad imfile

$InputFileName /var/log/fhem/fhem.log
$InputFileTag FHEM:
$InputFileStateFile /var/spool/rsyslog/fhem
$InputFilePollInterval 10
$InputRunFileMonitor

*.*   @IP_NAS:514

/var/log/fhem/fhem-$year-$month.log geht bei meiner rsyslog Version noch nicht.
Titel: Antw:FHEM.log ins Syslog
Beitrag von: Ruebezahl am 22 April 2016, 22:34:03
Ich greife dieses Thema noch einmal auf, weil mir inzwischen wegen SD-Kartenproblemen und gerade dem Logging mehrfach FHEM auf die Nase gefallen ist, Raspberry und SD-Karten sind ein eigenes Thema  >:(

Also wen es auch ein wenig drückt, hier mal meine Lösung:

ich habe im Ramdrive eine FIFO erstellt (mkfifo /ramdrive/fhem.fifo) und diese FIFO als logfile in FHEM angegeben.
Dann habe ich ein kleines Perlskript exterrn laufen, welches diese FIFO liest und dann weiterleitet zum Rsyslog Daemon
Das Skript ist sehr simpel gestrickt, sollte aber unbedingt vor dem Start von FHEM schon am "arbeiten" sein.
(Sys::Syslog muss installiert sein für dieses Skript)

        use Sys::Syslog;                        # all except setlogsock()
        use Sys::Syslog qw(:standard :macros);  # standard functions & macros

        my $fifo_file = "/ramdrive/fhem.fifo";
        my $ident = "FHEM";


        my $fifo_fh;

        openlog($ident, "ndelay,pid", LOG_USER);


        open($fifo_fh, "+< $fifo_file") or die "The FIFO file \"$fifo_file\" is missing, and this program can't run without it.";

        # just keep reading from the fifo and processing the events we read
        while (<$fifo_fh>)
        {
                    syslog("info", $_);
        }

        # should never really come down here ...
        closelog();
        close $fifo_fh;
        exit(0);


den ganzen Prozess sollte man natürlich in das Start/Stop Skript einbauen, besonders das mkfifo, weil das ramdrive nach dem boot sehr leer ist.