diff --git a/fhem/FHEM/01_FHEMWEB.pm b/fhem/FHEM/01_FHEMWEB.pm
index 40f6619d3..3a6261b1e 100644
--- a/fhem/FHEM/01_FHEMWEB.pm
+++ b/fhem/FHEM/01_FHEMWEB.pm
@@ -181,6 +181,8 @@ FHEMWEB_Initialize($)
iconPath
longpoll:0,1,websocket
longpollSVG:1,0
+ logDevice
+ logFormat
menuEntries
mainInputLength
nameDisplay
@@ -622,6 +624,7 @@ FW_finishRead($$$)
my $expires = ($cacheable ?
"Expires: ".FmtDateTimeRFC1123($hash->{LASTACCESS}+900)."\r\n" :
"Cache-Control: no-cache, no-store, must-revalidate\r\n");
+ FW_log($arg, $length) if(AttrVal($FW_wname, "logDevice", undef));
Log3 $FW_wname, 4,
"$FW_wname: $arg / RL:$length / $FW_RETTYPE / $compressed / $expires";
if( ! FW_addToWritebuffer($hash,
@@ -3495,6 +3498,36 @@ FW_show($$)
return undef;
}
+sub
+FW_log($$)
+{
+ my ($arg, $length) = @_;
+
+ my $c = $defs{$FW_cname};
+ my $fmt = AttrVal($FW_wname, "logFormat", '%h %l %u %t "%r" %>s %b');
+ my $rc = $FW_httpRetCode;
+ $rc =~ s/ .*//;
+ $arg = substr($arg,0,5000)."..." if(length($arg) > 5000);
+
+ my @t = localtime;
+ my %cp = (
+ h=>$c->{PEER},
+ l=>"-",
+ u=>$c->{AuthenticatedUser} ? $c->{AuthenticatedUser} : "-",
+ t=>strftime("%d/%b/%Y:%H:%M:%S %z",@t),
+ r=>$arg,
+ ">s"=>$rc,
+ b=>$length
+ );
+
+ $fmt =~ s/%([^" ]*)/defined($cp{$1}) ? $cp{$1} : "%$1"/ge;
+ $fmt =~ s/%{([^" ]*)}/defined($FW_httpheader{$1}) ?$FW_httpheader{$1}:"$1"/ge;
+
+ my $ld = AttrVal($FW_wname, "logDevice", undef);
+ CallFn($ld, "LogFn", $defs{$ld}, $fmt) if($defs{$ld});
+}
+
+
1;
=pod
@@ -3911,6 +3944,20 @@ FW_show($$)
+
+
logDevice fileLogName
+ Name of the FileLog instance, which is used to log each FHEMWEB access.
+ To avoid writing wrong lines to this file, the regexp should be set to
+ :Log
+
+
+
+ logFormat ...
+ Default is the Apache common Format (%h %l %u %t "%r" %>s %b).
+ Currently only these "short" place holders are replaced. Additionally,
+ each HTTP Header X can be accessed via %{X}.
+
+
longpoll [0|1|websocket]
If activated, the browser is notifed when device states, readings or
@@ -4655,6 +4702,21 @@ FW_show($$)
+
+ logDevice fileLogName
+ Name einer FileLog Instanz, um Zugriffe zu protokollieren.
+ Um das Protokollieren falscher Einträge zu vermeiden, sollte das
+ FileLog Regexp der Form :Log sein.
+
+
+
+ logFormat ...
+ Voreinstellung ist das Apache common Format (%h %l %u %t "%r" %>s %b).
+ Z.Zt. werden nur diese "kurzen" Platzhalter ersetzt, weiterhin kann man
+ mit %{X} den HTTP-Header-Eintrag X spezifizieren.
+
+
+
longpoll [0|1|websocket]
Falls gesetzt, FHEMWEB benachrichtigt den Browser, wenn
diff --git a/fhem/FHEM/92_FileLog.pm b/fhem/FHEM/92_FileLog.pm
index 1b3ba6e2c..cd1e424da 100644
--- a/fhem/FHEM/92_FileLog.pm
+++ b/fhem/FHEM/92_FileLog.pm
@@ -38,6 +38,7 @@ FileLog_Initialize($)
#$hash->{DeleteFn} = "FileLog_Delete";
$hash->{NotifyFn} = "FileLog_Log";
$hash->{AttrFn} = "FileLog_Attr";
+ $hash->{LogFn} = "FileLog_DirectLog";
# logtype is used by the frontend
no warnings 'qw';
my @attrList = qw(
@@ -252,6 +253,25 @@ FileLog_Switch($)
return 0;
}
+sub
+FileLog_LogTailWork($$$$)
+{
+ my ($log, $ln, $tn, $written) = @_;
+ my $fh = $log->{FH};
+ if($fh) {
+ $fh->flush;
+ # Skip sync, it costs too much HD strain, esp. on SSD
+ # $fh->sync if !($^O eq 'MSWin32'); #not implemented in Windows
+ }
+ my $owr = ReadingsVal($ln, "linesInTheFile", 0);
+ my $eot = AttrVal($ln, "eventOnThreshold", 0);
+ if($eot && ($owr+$written) % $eot == 0) {
+ readingsSingleUpdate($log, "linesInTheFile", $owr+$written, 1);
+ } else {
+ setReadingsVal($log, "linesInTheFile", $owr+$written, $tn);
+ }
+}
+
#####################################
sub
FileLog_Log($$)
@@ -322,23 +342,21 @@ FileLog_Log($$)
}
}
return "" if(!$written);
-
- if($fh) {
- $fh->flush;
- # Skip sync, it costs too much HD strain, esp. on SSD
- # $fh->sync if !($^O eq 'MSWin32'); #not implemented in Windows
- }
- my $owr = ReadingsVal($ln, "linesInTheFile", 0);
- my $eot = AttrVal($ln, "eventOnThreshold", 0);
- if($eot && ($owr+$written) % $eot == 0) {
- readingsSingleUpdate($log, "linesInTheFile", $owr+$written, 1);
- } else {
- setReadingsVal($log, "linesInTheFile", $owr+$written, $tn);
- }
-
+ FileLog_LogTailWork($log, $ln, $tn, $written);
return "";
}
+#####################################
+sub
+FileLog_DirectLog($$)
+{
+ my ($log, $txt) = @_;
+ FileLog_Switch($log);
+ my $fh = $log->{FH};
+ print $fh $txt,"\n";
+ FileLog_LogTailWork($log, $log->{NAME}, TimeNow(), 1);
+}
+
###################################
sub
FileLog_Attr(@)