Mehrere DbLog Devices

Begonnen von nesges, 12 Februar 2015, 11:52:36

Vorheriges Thema - Nächstes Thema

nesges

DbLog per Regex einzuschränken kann mitunter mühsam werden. Ich habe daher testweise mal mehrere DbLog-Devices angelegt:

define DBLOG1 DbLog sky.db.conf [AWKSB]_(HUMID|THERMO|HEIZUNG|FENSTER).*:(temperature|humidity|desiredTemperature|valveposition|onoff|T).*
define DBLOG2 DbLog sky.db.conf (Wetter|WETTER|SYSMON|FRITZ|FRITZ2):.*
define DBLOG3 DbLog sky.db.conf .*:([Bb]attery|state)
define DBLOG4 DbLog sky.db.conf CUL1:credit10ms


Bisher konnte ich keine Probleme feststellen, alle erwarteten Readings werden in die Datenbank geschrieben. Spricht irgend etwas dagegen so zu verfahren? Falls nicht würde ich das im Wiki ergänzen, da die Frage nach einer Vereinfachung der Notation schon öfter kam.

betateilchen

Es ist völlig normal, mehrere DbLog Devices zu haben - wo ist das Problem? Wo steht, dass das nicht gehen soll/darf/kann?

Grundsätzlich ist das aber eher dazu gedacht, mehrere unterschiedliche Datenbanken/Tabellen für verschiedene readings zu haben. Denn das, was Du da tust, ist schon ziemlich schräg und eigentlich genau das, wofür man DbLog eigentlich nicht einsetzt. Du forkst nämlich irgendwann unzählige Datenbankprozesse immer auf die gleiche Datenbank, bis irgendwann die Performance Deines gesamten fhem in die Knie geht.

Empfehlenswert und/oder sinnvoll ist Dein Vorgehen nicht.

Du sollest das bitte nicht auch noch versuchen, per Wiki zu verbreiten.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

nesges

Das eigentliche Problem ist, dass DbLog addRegexpPart und die damit einhergehende Regex-Listen-Notation (wie zB in FileLog) nicht implementiert, sondern nur einen einzigen Regex auswertet (der zudem aus zweien concateniert ist, was die Sache zusätzlich verkompliziert). Eine etwas komplexere Auswahl an Logparametern fällt dadurch nicht nur sehr schwer, sondern wird verunmöglicht. Betrachtet man mein Beispiel, stellt man schnell fest, dass die Obermenge aus DBLOG2 und DBLOG3 mit .*:.* definiert ist. Lösbar ist das Problem dann nur noch durch relativ hohen Aufwand mit DbLogExclude. Sollte ich allerdings eine alternative, einfache Lösung übersehen habe, bin ich für einen Hinweis sehr dankbar.

Es damit aus Performancegründen nicht zu übertreiben ist auf jeden Fall ein guter Hinweis. Mein Beispiel lässt sich leicht auf drei Devices reduzieren, indem man DBLOG1 und DBLOG4 zusammen fasst; idR sollte man damit auch auskommen.

chris1284

ich hatte selbes "problem". entweder unzählige sachen  in den regexp mit aufnehmen oder excluden.
ich habe mich für letzteres entschieden. jedes neue device bekommt bei mir automatisch DbLogExclude verpasst (notify global:DEFINED.* attr $EVTPART1 DbLogExclude .*).
wenn ich ein device loggen will muss ich nur noch das attr löschen / anpassen (alle readings im device excluden die ich nicht will). ggf noch mit event-on-change-reading die einträge minimieren. das iat bei mir in summer der geringere aufwand.

warum ich sachen in einzelnen dbs loggen sollte erschoss sich bisher nicht. eine db mit allen daten reicht mir. es macht sich auch blöd wenn man db übergreifend plotten will OHNE weiter module wie logProxy usw

nesges

Zitat von: chris1284 am 19 Februar 2015, 21:19:21notify global:DEFINED.* attr $EVTPART1 DbLogExclude .*

Das ist sexy! :-)

Zitatwarum ich sachen in einzelnen dbs loggen sollte erschoss sich bisher nicht. eine db mit allen daten reicht mir. es macht sich auch blöd wenn man db übergreifend plotten will OHNE weiter module wie logProxy usw

Meine DBLOG*-Devices nutzen alle die gleiche Datenbank, das ist der "Trick" dabei und gleichzeitig das von betateilchen genannte Problem.

marvin78

Zitat von: chris1284 am 19 Februar 2015, 21:19:21


warum ich sachen in einzelnen dbs loggen sollte erschoss sich bisher nicht. eine db mit allen daten reicht mir. es macht sich auch blöd wenn man db übergreifend plotten will OHNE weiter module wie logProxy usw

Ganz einfach: Es gibt Daten, die man eventuell länger vorhalten möchte, als andere (Wetterdaten, Energieverbrauch). Diese loggt man in eine gesonderte DB um die Tabelle, welche die anderen Daten enthält, leicht mit FHEM Mitteln (deleteOldDays) übersichtlich halten zu können. Es gibt sicher auch noch andere sinnvolle Gründe, wie bspw. die Verwendung einiger spezieller Daten in externen Anwendungen.

Es macht natürlich keinen Sinn, Daten in verschiedenen DBs zu loggen, die man danach wieder gemeinsam plotten möchte. Planung ist eben alles. Auch RegEx in DB-Log ist leichter, wenn man die Device-Namen logisch wählt. Ich denke, die Kombination von RegEx und DbLogExclude macht die Sache schon recht leicht.

chris1284

#6
Zitat von: nesges am 19 Februar 2015, 21:39:56
Das ist sexy! :-)

ich hatte auch schon einen vorschlag gemacht ein DblogInclude mit einzubauen. das würde bei vielen devices (wie zb sysmon) den aufwand start reduzieren wenn nicht 100 readings excluden müsste sondern nur 2 includen  ;)

einfach dblog definieren mit "logge nix" und nu in den devices zb temp und hum includen. für euch mit mehreren dbs wäre hier dann evtlnoch die angabe der db interessant.

@marvin78: klar kann man die länger zu lagernden daten in eine extra db packen, man könnte aber auch die anderen einfach  regelmäßig aus der großen "tabelle" löschen. ist sicher geschmackssache.

SventeHof

Hallo Chris,

a)
wie kann man denn im Device hinterlegen, welche DB genutzt werden soll?

b)
Hast du ein Beispiel, wie man die "anderen" einfach aus der Tabelle löschen kann.

Gruß
Sven

betateilchen

Zitat von: SventeHof am 17 Januar 2016, 17:32:12
a)
wie kann man denn im Device hinterlegen, welche DB genutzt werden soll?

Umgekehrt. Du sagst der Datenbank im define, welche devices (oder devicetypen) sie loggen soll. Das geht bis auf einzelne readings.


define fhemDbLog DbLog ./FHEM/logDB.cfg (.*:lumi.*|GW1_.*|.*:batVoltage.*|.*:measured-temp.*|.*:desired.*|.*:actuator.*|.*:valve.*|.*:Bb]attery:.*|.*:temperature.*|.*:humidity.*|.*:dewpoint.*|.*:pressure.*|Melder.*:.*|RM_.*:.*|sunDummy.*:.*|out_Regen.*:.*|.*_SenPwr.*|gds.*)
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

JoeALLb

Ich habe meine Datenbank dazu mit Partitionen versehen. Dann reicht ein log Device, und eine partition mit den Langzeitdaten. Die kurzzeitdaten werde  wieder in Wochentage aufgeteilt, so kann ich selbst am raspi ohne Verzögerung alle alten Daten sofort ohne Hänger löschen.... Und auf die Langzeittabelle habe ich sogar einen löschschutz in den Rechten hinterlegt.
Die Aufteilung kann ich entweder per triggern leicht anpassen oder per alter table die partitionsdefinition anpassen...
FHEM-Server auf IntelAtom+Debian (8.1 Watt), KNX,
RasPi-2 Sonos-FHEM per FHEM2FHEM,RasPi-3 Versuchs-RasPi für WLAN-Tests
Gateways: DuoFern Stick, CUL866 PCA301, CUL HM, HMLan, JeeLink, LaCrosse,VCO2
Synology. Ardurino UNO für 1-Wire Tests, FB7270

SventeHof

Alles klar .. danke für die Antworten!
Wie hast du das mit den Partitionen bei den Datenbanken gemacht? Partitionen kenne ich gerade nicht im Bereich von Datenbanken..

Gruß
Sven

JoeALLb

Zitat von: SventeHof am 17 Januar 2016, 19:36:37
Wie hast du das mit den Partitionen bei den Datenbanken gemacht? Partitionen kenne ich gerade nicht im Bereich von Datenbanken..

Beispiel: Aufteilung in 2*7 Untertabellen. Abfragen kannst Du wie gewohnt nur die Tabelle history, wenn Du aber beispielsweise alle Logs von Montag löschen willst reicht ein
ALTER TABLE history DROP PARTITION monNolong  ;
Das geht praktisch ohne Verzögerung selbst am rpi. Nun, ich will eigentlich gar keine ganzen Montags-Logs löschen, nutze das aber
da die Aufteilung auf 7 Tabellen am langsamen rpi mit SD-Speicher schneller geht.

CREATE TABLE history (
`TIMESTAMP` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
`DEVICE` VARCHAR(32) NOT NULL DEFAULT '',
`TYPE` VARCHAR(32) NULL DEFAULT NULL,
`EVENT` VARCHAR(512) NULL DEFAULT NULL,
`READING` VARCHAR(32) NOT NULL DEFAULT '',
`VALUE` VARCHAR(32) NULL DEFAULT NULL,
`UNIT` VARCHAR(32) NULL DEFAULT NULL,
`Longterm` TINYINT NOT NULL DEFAULT 0,
PRIMARY KEY (`DEVICE`, `READING`, `TIMESTAMP`,`Longterm`)
)
COLLATE='latin1_swedish_ci'
    PARTITION BY RANGE (WEEKDAY(timestamp))
    SUBPARTITION BY HASH (Longterm) (
        PARTITION mon VALUES LESS THAN (1) (
            SUBPARTITION monNolong  ENGINE = MyISAM,
            SUBPARTITION monLong  ENGINE = MyISAM
        ),
        PARTITION tue VALUES LESS THAN (2) (
            SUBPARTITION tueNolong ENGINE = MyISAM,
            SUBPARTITION tueLong ENGINE = MyISAM
        ),
        PARTITION wen VALUES LESS THAN (3) (
            SUBPARTITION wenNolong ENGINE = MyISAM,
            SUBPARTITION wenLong ENGINE = MyISAM
        ),
        PARTITION tur VALUES LESS THAN (4) (
            SUBPARTITION turNolong ENGINE = MyISAM,
            SUBPARTITION turLong ENGINE = MyISAM
        ),
        PARTITION fri VALUES LESS THAN (5) (
            SUBPARTITION friNolong ENGINE = MyISAM,
            SUBPARTITION friLong ENGINE = MyISAM
        ),
        PARTITION sat VALUES LESS THAN (6) (
            SUBPARTITION satNolong ENGINE = MyISAM,
            SUBPARTITION satLong ENGINE = MyISAM
        ),
        PARTITION sun VALUES LESS THAN (7) (
            SUBPARTITION sunNolong ENGINE = MyISAM,
            SUBPARTITION sunLong ENGINE = MyISAM
        )
    );

Achtung: Ich benutze bewußt KEINE Unicode-Tabelle und habe bewußt den Index angepasst, dass doppelte Einträge bei mir nicht geloggt werden können.

Über einen Trigger steuere ich nun, ob bei einem neuen Eintrag in die Spalte Longterm eine 1 oder eine 0 kommt.
Will ich nun am Freitag die nicht dauerhaft benätigten Logeinträge von Montag löschen, führe ich den oben genannten Befehl aus.
FHEM-Server auf IntelAtom+Debian (8.1 Watt), KNX,
RasPi-2 Sonos-FHEM per FHEM2FHEM,RasPi-3 Versuchs-RasPi für WLAN-Tests
Gateways: DuoFern Stick, CUL866 PCA301, CUL HM, HMLan, JeeLink, LaCrosse,VCO2
Synology. Ardurino UNO für 1-Wire Tests, FB7270

betateilchen

Zitat von: SventeHof am 17 Januar 2016, 19:36:37
Partitionen kenne ich gerade nicht im Bereich von Datenbanken..

Das funktioniert auch nicht mit allen SQL-Datenbanken und setzt ein ziemlich tiefes Verständnis von Datenbank-Engines und deren Möglichkeiten voraus.
Meines Erachtens für fhem etwas overkill.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

linuzer

Zitat von: chris1284 am 19 Februar 2015, 21:19:21
jedes neue device bekommt bei mir automatisch DbLogExclude verpasst (notify global:DEFINED.* attr $EVTPART1 DbLogExclude .*).

Ich habe das bei mir genauso eingetragen, aber es funktioniert nicht. Habe ich irgend etwas übersehen? Hier mein ganzer Eintrag:
define nDbLogExclude notify global:DEFINED.* attr $EVTPART1 DbLogExclude .*

Sunny

#14
Moin,

Du hast die Klammern vergessen. 8)

Viele lesende Grüße
Sunny
FHEM 6.0 (RPi's 1b-4,CeleronM,Odroid C1+)
1-Wire (DS18B20,DS2406) |miniCUL|miniCUL868WLAN|HM|IT(-1500,LR-3500) |FB6591,FB7490,FB7580|DECT200|Powerline546E|520E|openwrt
Anfänger: Linux,FHEM+Perl