Skip to content

Commit

Permalink
custom_logging: implement custom data logger
Browse files Browse the repository at this point in the history
  • Loading branch information
yashlamba committed Dec 12, 2024
1 parent a11ff41 commit 506ea92
Show file tree
Hide file tree
Showing 5 changed files with 143 additions and 0 deletions.
7 changes: 7 additions & 0 deletions site/zenodo_rdm/custom_logging/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2023 CERN.
#
# Zenodo-RDM is free software; you can redistribute it and/or modify
# it under the terms of the MIT License; see LICENSE file for more details.
"""Custom logging module."""
11 changes: 11 additions & 0 deletions site/zenodo_rdm/custom_logging/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2024 CERN.
#
# ZenodoRDM is free software; you can redistribute it and/or modify
# it under the terms of the MIT License; see LICENSE file for more details.

"""Logging config."""

CUSTOM_LOGGING_INDEX = "custom-logs"
"""Custom logs index."""
53 changes: 53 additions & 0 deletions site/zenodo_rdm/custom_logging/ext.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2024 CERN.
#
# ZenodoRDM is free software; you can redistribute it and/or modify
# it under the terms of the MIT License; see LICENSE file for more details.

"""ZenodoRDM custom logging module."""

import logging

from zenodo_rdm.custom_logging.handlers import OpenSearchHandler

from . import config

CUSTOM_LOGGING_LEVEL = 1000


def custom(self, key, message, *args, **kws):
"""Log level custom method."""
if not isinstance(message, dict):
raise ValueError("Message should be a dict")
if self.isEnabledFor(CUSTOM_LOGGING_LEVEL):
message["key"] = key
self._log(CUSTOM_LOGGING_LEVEL, message, args, **kws)


class ZenodoCustomLogging:
"""Zenodo custom logging extension."""

def __init__(self, app=None):
"""Extension initialization."""
if app:
self.init_app(app)

@staticmethod
def init_config(app):
"""Initialize configuration."""
for k in dir(config):
if k.startswith("CUSTOM_LOGGING_"):
app.config.setdefault(k, getattr(config, k))

def init_app(self, app):
"""Flask application initialization."""
logging.addLevelName(CUSTOM_LOGGING_LEVEL, "CUSTOM")
logging.Logger.custom = custom
handler = OpenSearchHandler()
for h in app.logger.handlers:
if isinstance(h, handler.__class__):
break
else:
app.logger.addHandler(handler)
self.init_config(app)
43 changes: 43 additions & 0 deletions site/zenodo_rdm/custom_logging/handlers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2024 CERN.
#
# ZenodoRDM is free software; you can redistribute it and/or modify
# it under the terms of the MIT License; see LICENSE file for more details.

"""Custom logging handler for ZenodoRDM."""

import logging
from datetime import datetime, timezone

from flask import current_app
from invenio_search.proxies import current_search_client


class OpenSearchHandler(logging.Handler):
"""Open search handler for logs."""

def __init__(self):
"""Constructor."""
logging.Handler.__init__(self)

def _build_index_name(self):
"""Build index name."""
return f"{current_app.config.get('SEARCH_INDEX_PREFIX')}-{current_app.config.get('CUSTOM_LOGGING_INDEX')}"

def emit(self, record):
"""Emit, take log action."""
if record.levelname == "CUSTOM":
key = record.msg.pop("key")
document = {
"timestamp": datetime.fromtimestamp(
record.created, timezone.utc
).isoformat(),
"key": key,
"context": record.msg,
}

current_search_client.index(
index=self._build_index_name(),
body=document,
)
29 changes: 29 additions & 0 deletions site/zenodo_rdm/index_templates/os-v2/custom-logs-template.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"index_patterns": [
"__SEARCH_INDEX_PREFIX__custom-logs-*"
],
"template": {
"aliases": {
"__SEARCH_INDEX_PREFIX__custom-logs": {}
},
"settings": {
"index": {
"refresh_interval": "5s"
}
},
"mappings": {
"properties": {
"timestamp": {
"type": "date"
},
"key": {
"type": "keyword"
},
"context": {
"type": "object",
"dynamic": true
}
}
}
}
}

0 comments on commit 506ea92

Please sign in to comment.