diff --git a/gettattr/Kreis_gettattr.py b/gettattr/Kreis_gettattr.py deleted file mode 100644 index d4b1e27..0000000 --- a/gettattr/Kreis_gettattr.py +++ /dev/null @@ -1,20 +0,0 @@ -from math import pi as pi - - -class Kreis_gettattr: - def __init__(self, radius): - self.radius = radius - self.operators ={ - 'durchmesser': lambda x: self.radius * 2 - 'umfang': lambda x: self.durchmesser * pi - 'flaeche': lambda: x: self.radius**2 *pi - } - - def __getattr(self, name): - if name not in self.operators: - raise TypeError(f'unbekannte Operation {name}') - - return { - } [name] - - diff --git a/teil13/.gitignore b/teil13/.gitignore index c7fb3aa..5a73591 100644 --- a/teil13/.gitignore +++ b/teil13/.gitignore @@ -1,2 +1,2 @@ -./__pycache__ +__pycache__ ./network/__pycache__/* diff --git a/logging-config/.gitignore b/teil27/.gitignore similarity index 54% rename from logging-config/.gitignore rename to teil27/.gitignore index 5a79b2d..e99001d 100644 --- a/logging-config/.gitignore +++ b/teil27/.gitignore @@ -1,3 +1,6 @@ example.py ex2.py *.log +__pycache__ +db.ini + diff --git a/teil27/JSONFormatter.py b/teil27/JSONFormatter.py new file mode 100644 index 0000000..af916df --- /dev/null +++ b/teil27/JSONFormatter.py @@ -0,0 +1,10 @@ +import logging +import logging.config +import json +ATTR_TO_JSON = ['created', 'filename', 'funcName', 'levelname', 'lineno', 'module', 'msecs', 'msg', 'name', 'pathname', 'process', 'processName', 'relativeCreated', 'thread', 'threadName'] +class JsonFormatter: + def format(self, record): + obj = {attr: getattr(record, attr) + for attr in ATTR_TO_JSON} + return json.dumps(obj, indent=4) + diff --git a/teil27/db.ini.sample b/teil27/db.ini.sample new file mode 100644 index 0000000..41f7420 --- /dev/null +++ b/teil27/db.ini.sample @@ -0,0 +1,8 @@ +[pidb] +host=database +user=piuser +password= +database=pidb + + + diff --git a/teil27/dbhandler.py b/teil27/dbhandler.py new file mode 100644 index 0000000..9856d9f --- /dev/null +++ b/teil27/dbhandler.py @@ -0,0 +1,75 @@ +# Datei dbhandler.py +import mysql.connector +import datetime +import configparser +import logging +from logging import config +import json + + + + +class DBHandler(logging.Handler): + def __init__(self): + logging.Handler.__init__(self) + # Datenbank Konfiguration lesen + confparser = configparser.ConfigParser() + confparser.read('db.ini') + # Verbindung zur DB herstellen + self.connection= mysql.connector.connect(host=confparser['pidb']['host'],user = confparser['pidb']['user'],password = confparser['pidb']['password'],database = confparser['pidb']['database']) + # Tabelle anlegen, falls noch keine existiert. + self.connection.cursor().execute('''CREATE TABLE IF NOT EXISTS logs ( + id INTEGER PRIMARY KEY AUTO_INCREMENT, + zeit VARCHAR(50), + level VARCHAR(8), + message VARCHAR(40), + logger_name VARCHAR(25), + filename VARCHAR(60), + line INTEGER)''') + self.connection.commit() + + # Bei Löschung der Klasseninstanz, Connection schliessen + def __del__(self): + if self.connection != None: + self.connection.close() + self.connection = None + + # LogRecord in die DB schreiben + def emit(self, record): + try: + # Log-Daten in ein Tupel extrahieren + log_entry = (datetime.datetime.utcnow().isoformat(), + record.levelname, + record.getMessage(), + record.name, + record.pathname, + record.lineno) + + # Log in die Datenbank einfügen + cursor = self.connection.cursor() + cursor.execute('''INSERT INTO logs (zeit, level, message, logger_name, filename, line) + VALUES (%s, %s, %s, %s, %s, %s)''', log_entry) + self.connection.commit() + cursor.close() + + except Exception as e: + # im Fehlerfall den LogRecord nach "oben" weiterreichen. + self.handleError(record) + +# Config aus JSON Datei laden und setzen +with open('handler_config.json') as file_config: + config.dictConfig(json.load(file_config)) +# Logging testen +def testlogging(): + print('testlogging() aufgerufen.') + logging.debug('Diese Zeile wird ausgefiltert.') + logging.debug('DEBUG/Druckdaten werden gesendet.') + logging.info('INFO/Es werden 2 Seiten gedruckt') + logging.debug('Diese Zeile wird auch ausgefiltert.') + logging.warning('WARN/nicht genügend Papier im Drucker') + logging.error('ERROR/Drucker nicht gefunden.') + logging.critical('CRITICAL/Drucker brennt') + +if __name__ == '__main__': + testlogging() + diff --git a/logging-config/filterlogging.py b/teil27/filterlogging.py similarity index 100% rename from logging-config/filterlogging.py rename to teil27/filterlogging.py diff --git a/logging-config/halloween.py b/teil27/halloween.py similarity index 65% rename from logging-config/halloween.py rename to teil27/halloween.py index c71898e..ff553f9 100644 --- a/logging-config/halloween.py +++ b/teil27/halloween.py @@ -1,7 +1,19 @@ +#encoding: utf-8 import logging from logging import config import json import random +import JSONFormatter + +#JSON Formatter +ATTR_TO_JSON = ['created', 'filename', 'funcName', 'levelname', 'lineno', 'module', 'msecs', 'msg', 'name', 'pathname', 'process', 'processName', 'relativeCreated', 'thread', 'threadName'] +class JsonFormatter: + def format(self, record): + obj = {attr: getattr(record, attr) + for attr in ATTR_TO_JSON} + return json.dumps(obj, indent=4) + +#CustomFilter class HalloweenFilter(logging.Filter): @@ -14,7 +26,7 @@ class HalloweenFilter(logging.Filter): # Der Unsichtbare soll keine Spuren im Logfile hinterlassen. return record.getMessage().lower().find('unsichtbar') == -1 -visitors = ['Werwolf','Gespenst','Hexe','Unsichtbarer','Vampir','Dämon','Gorilla','Hulk','Mumie'] +visitors = ['Werwolf','Gespenst','Hexe','Unsichtbarer','Vampir','Dämon','Gorilla','Monster','Mumie'] treats = ['Bonbons','Twinkies','Lollis','Schokoladen','Kuchen', 'Äpfel'] diff --git a/logging-config/halloween_log_conf.json b/teil27/halloween_log_conf.json similarity index 86% rename from logging-config/halloween_log_conf.json rename to teil27/halloween_log_conf.json index bda18a7..349b4d3 100644 --- a/logging-config/halloween_log_conf.json +++ b/teil27/halloween_log_conf.json @@ -9,7 +9,10 @@ "std_out":{ "format": "%(asctime)s : %(levelname)s : %(lineno)d : %(message)s", "datefmt":"%I:%M:%S %d.%m.%Y" - } + }, + "json": { + "()": "__main__.JsonFormatter" + } }, "handlers":{ "console":{ @@ -18,7 +21,7 @@ "level": "DEBUG" }, "file":{ - "formatter":"std_out", + "formatter":"json", "class":"logging.FileHandler", "level":"DEBUG", "filename" : "halloween.log", diff --git a/teil27/handler_config.json b/teil27/handler_config.json new file mode 100644 index 0000000..c09a425 --- /dev/null +++ b/teil27/handler_config.json @@ -0,0 +1,33 @@ +{ + "version":1, + "formatters":{ + "std_out":{ + "format": "%(asctime)s : %(levelname)s : %(module)s : %(funcName)s : %(lineno)d : (Process Details : (%(process)d, %(processName)s), Thread Details : (%(thread)d, %(threadName)s))\nLog : %(message)s", + "datefmt":"%d-%m-%Y %I:%M:%S" + } + }, + "handlers":{ + "console":{ + "formatter": "std_out", + "class": "logging.StreamHandler", + "level": "DEBUG" + }, + "db":{ + "formatter": "std_out", + "()": "__main__.DBHandler", + "level": "DEBUG" + }, + "file":{ + "formatter":"std_out", + "class":"logging.FileHandler", + "level":"DEBUG", + "filename" : "raspithek.log" + } + }, + "root":{ + "handlers":["console","file","db"], + "level": "DEBUG" + } + +} + diff --git a/logging-config/log_config.json b/teil27/log_config.json similarity index 100% rename from logging-config/log_config.json rename to teil27/log_config.json diff --git a/logging-config/testloggingconf.py b/teil27/testloggingconf.py similarity index 100% rename from logging-config/testloggingconf.py rename to teil27/testloggingconf.py