log http endpoint added

This commit is contained in:
manuel83 2019-08-05 23:00:18 +02:00
parent 8200c48dfc
commit bbbfe92aab
12 changed files with 657 additions and 277 deletions

File diff suppressed because it is too large Load diff

View file

@ -38,6 +38,8 @@ class JobController(object):
self.cbpi.app.on_startup.append(spawn_job) self.cbpi.app.on_startup.append(spawn_job)
async def start_job(self, method, name, type): async def start_job(self, method, name, type):
scheduler = get_scheduler_from_app(self.cbpi.app) scheduler = get_scheduler_from_app(self.cbpi.app)
return await scheduler.spawn(method, name, type) return await scheduler.spawn(method, name, type)

View file

@ -5,6 +5,8 @@ import os
from logging.handlers import RotatingFileHandler from logging.handlers import RotatingFileHandler
from time import strftime, localtime from time import strftime, localtime
import pandas as pd import pandas as pd
import zipfile
class LogController: class LogController:
@ -50,6 +52,7 @@ class LogController:
# remove duplicates # remove duplicates
names = set(names) names = set(names)
print(names)
result = None result = None
def dateparse(time_in_secs): def dateparse(time_in_secs):
@ -89,6 +92,8 @@ class LogController:
data[name] = result[name].interpolate(limit_direction='both', limit=10).tolist() data[name] = result[name].interpolate(limit_direction='both', limit=10).tolist()
else: else:
data[name] = result.interpolate().tolist() data[name] = result.interpolate().tolist()
print(data)
return data return data
@ -98,9 +103,10 @@ class LogController:
:param name: log name as string. pattern /logs/sensor_%s.log* :param name: log name as string. pattern /logs/sensor_%s.log*
:return: list of log file names :return: list of log file names
''' '''
return = glob.glob('./logs/sensor_%s.log*' % name)
async def clear_log(self, name:str ) -> str: return [os.path.basename(x) for x in glob.glob('./logs/sensor_%s.log*' % name)]
def clear_log(self, name:str ) -> str:
''' '''
:param name: log name as string. pattern /logs/sensor_%s.log* :param name: log name as string. pattern /logs/sensor_%s.log*
@ -108,12 +114,48 @@ class LogController:
''' '''
all_filenames = glob.glob('./logs/sensor_%s.log*' % name) all_filenames = glob.glob('./logs/sensor_%s.log*' % name)
for f in all_filenames: for f in all_filenames:
print(f)
os.remove(f) os.remove(f)
if name in self.datalogger: if name in self.datalogger:
del self.datalogger[name] del self.datalogger[name]
def get_all_zip_file_names(self, name: str) -> list:
'''
Return a list of all zip file names
:param name:
:return:
'''
return [os.path.basename(x) for x in glob.glob('./logs/*-sensor-%s.zip' % name)]
def clear_zip(self, name:str ) -> None:
"""
clear all zip files for a sensor
:param name: sensor name
:return: None
"""
all_filenames = glob.glob('./logs/*-sensor-%s.zip' % name)
for f in all_filenames:
os.remove(f)
def zip_log_data(self, name: str) -> str:
"""
:param name: sensor name
:return: zip_file_name
"""
formatted_time = strftime("%Y-%m-%d-%H_%M_%S", localtime())
file_name = './logs/%s-sensor-%s.zip' % (formatted_time, name)
zip = zipfile.ZipFile(file_name, 'w', zipfile.ZIP_DEFLATED)
all_filenames = glob.glob('./logs/sensor_%s.log*' % name)
for f in all_filenames:
zip.write(os.path.join(f))
zip.close()
return file_name

View file

@ -35,6 +35,7 @@ from cbpi.controller.translation_controller import TranslationController
from cbpi.http_endpoints.http_translation import TranslationHttpEndpoint from cbpi.http_endpoints.http_translation import TranslationHttpEndpoint
from cbpi.http_endpoints.http_plugin import PluginHttpEndpoints from cbpi.http_endpoints.http_plugin import PluginHttpEndpoints
from cbpi.http_endpoints.http_system import SystemHttpEndpoints from cbpi.http_endpoints.http_system import SystemHttpEndpoints
from cbpi.http_endpoints.http_log import LogHttpEndpoints
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -104,6 +105,7 @@ class CraftBeerPi():
self.http_plugin = PluginHttpEndpoints(self) self.http_plugin = PluginHttpEndpoints(self)
self.http_system = SystemHttpEndpoints(self) self.http_system = SystemHttpEndpoints(self)
self.notification = NotificationController(self) self.notification = NotificationController(self)
self.http_log = LogHttpEndpoints(self)
self.login = Login(self) self.login = Login(self)
def _setup_shutdownhook(self): def _setup_shutdownhook(self):

View file

@ -31,8 +31,6 @@ class CustomSensor(CBPiSensor):
def get_state(self): def get_state(self):
return self.state return self.state
def get_value(self): def get_value(self):
return self.value return self.value

View file

@ -21,7 +21,6 @@ class CBPiMqttClient:
async def listen(self, topic, **kwargs): async def listen(self, topic, **kwargs):
if self.client is not None: if self.client is not None:
print(topic, kwargs)
await self.client.publish(topic, str.encode(json.dumps(kwargs, cls=ComplexEncoder)), QOS_0) await self.client.publish(topic, str.encode(json.dumps(kwargs, cls=ComplexEncoder)), QOS_0)
def setup(cbpi): def setup(cbpi):
@ -32,5 +31,5 @@ def setup(cbpi):
:param cbpi: the cbpi core :param cbpi: the cbpi core
:return: :return:
''' '''
print("MQTT REGISTER-------------") client = CBPiMqttClient(cbpi)
c = CBPiMqttClient(cbpi)

View file

@ -1,3 +1,3 @@
name: MQTT name: MQTT
version: 4.0 version: 4.0
active: false active: False

View file

@ -0,0 +1,63 @@
from aiohttp import web
from cbpi.utils.utils import json_dumps
from cbpi.api import request_mapping
class LogHttpEndpoints:
def __init__(self,cbpi):
self.cbpi = cbpi
self.cbpi.register(self, url_prefix="/log")
@request_mapping(path="/{name}/zip", method="POST", auth_required=False)
async def create_zip_names(self, request):
log_name = request.match_info['name']
data = self.cbpi.log.zip_log_data(log_name)
print(data)
return web.json_response(dict(filename=data), dumps=json_dumps)
@request_mapping(path="/{name}/zip", method="DELETE", auth_required=False)
async def clear_zip_names(self, request):
log_name = request.match_info['name']
self.cbpi.log.clear_zip(log_name)
return web.Response(status=204)
@request_mapping(path="/zip/download/{name}", method="GET", auth_required=False)
async def download_zip(self, request):
response = web.StreamResponse(
status=200,
reason='OK',
headers={'Content-Type': 'application/zip'},
)
await response.prepare(request)
log_name = request.match_info['name']
with open('./logs/%s.zip' % log_name, 'rb') as file:
for line in file.readlines():
await response.write(line)
await response.write_eof()
return response
@request_mapping(path="/{name}/zip", method="GET", auth_required=False)
async def get_zip_names(self, request):
log_name = request.match_info['name']
data = self.cbpi.log.get_all_zip_file_names(log_name)
return web.json_response(data, dumps=json_dumps)
@request_mapping(path="/{name}/files", method="GET", auth_required=False)
async def get_file_names(self, request):
log_name = request.match_info['name']
print(log_name)
data = self.cbpi.log.get_logfile_names(log_name)
return web.json_response(data, dumps=json_dumps)
@request_mapping(path="/{name}", method="GET", auth_required=False)
async def delete_log(self, request):
log_name = request.match_info['name']
data = await self.cbpi.log.get_data(log_name)
return web.json_response(data, dumps=json_dumps)
@request_mapping(path="/{name}", method="DELETE", auth_required=False)
async def delete_all_logs(self, request):
log_name = request.match_info['name']
await self.cbpi.log.clear_logs(log_name)
return web.Response(status=204)

View file

@ -1,3 +1,4 @@
import datetime
from json import JSONEncoder from json import JSONEncoder
@ -8,6 +9,8 @@ class ComplexEncoder(JSONEncoder):
if hasattr(obj, "to_json") and callable(getattr(obj, "to_json")): if hasattr(obj, "to_json") and callable(getattr(obj, "to_json")):
return obj.to_json() return obj.to_json()
elif isinstance(obj, datetime.datetime):
return obj.__str__()
else: else:
raise TypeError() raise TypeError()
except Exception as e: except Exception as e:

View file

@ -1,11 +1,9 @@
import logging import logging
import re
import weakref import weakref
from collections import defaultdict from collections import defaultdict
import aiohttp import aiohttp
from aiohttp import web from aiohttp import web
from cbpi.api import *
from voluptuous import Schema from voluptuous import Schema
from cbpi.utils import json_dumps from cbpi.utils import json_dumps

View file

@ -1,3 +1,4 @@
pandas
aiohttp==3.4.4 aiohttp==3.4.4
aiohttp-auth==0.1.1 aiohttp-auth==0.1.1
aiohttp-route-decorator==0.1.4 aiohttp-route-decorator==0.1.4

View file

@ -18,7 +18,7 @@ class UtilsTestCase(AioHTTPTestCase):
log_name = "test" log_name = "test"
#clear all logs #clear all logs
await self.cbpi.log.clear_log(log_name) self.cbpi.log.clear_log(log_name)
assert len(glob.glob('./logs/sensor_%s.log*' % log_name)) == 0 assert len(glob.glob('./logs/sensor_%s.log*' % log_name)) == 0
# write log entries # write log entries
@ -29,11 +29,13 @@ class UtilsTestCase(AioHTTPTestCase):
# read log data # read log data
data = await self.cbpi.log.get_data(log_name, sample_rate='1s') data = await self.cbpi.log.get_data(log_name, sample_rate='1s')
assert len(data["time"]) == 5 assert len(data["time"]) == 5
await self.cbpi.log.clear_log(log_name) assert self.cbpi.log.zip_log_data(log_name) is not None
self.cbpi.log.clear_zip(log_name)
self.cbpi.log.clear_log(log_name)