Skip to content

Commit

Permalink
update: extract logs into a separate module
Browse files Browse the repository at this point in the history
  • Loading branch information
mutantsan committed Mar 11, 2024
1 parent 48ef3af commit 951cd30
Show file tree
Hide file tree
Showing 22 changed files with 115 additions and 52 deletions.
14 changes: 8 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,24 +149,26 @@ To install ckanext-admin-panel:
None at present

## Enabling logging
To store the log messages, you have to initiate the database log table and create a handler in your `ckan.ini` file.
To store log messages in a database, you must enable the `admin_panel_log` extension, initialize the database log table,
and create a handler in your 'ckan.ini' file.

1. This command will initiate all missing tables: `ckan db pending-migrations --apply`
2. To register a handler you must specify it in your CKAN configuration file. Because of some CKAN specific, the logger must know the database URI to initiate itself. Provide it with `kwargs` option.
1. Add `admin_panel_log` to the `ckan.plugins` setting in your CKAN config file.
2. Initialize all missing tables with: `ckan db pending-migrations --apply`
3. To register a handler, you must specify it in your CKAN configuration file. Due to some CKAN specifics, the logger needs to know the database URI to initialize itself. Provide it with the `kwargs` option.
```
[handler_dbHandler]
class = ckanext.ap_main.log_handlers.DatabaseHandler
class = ckanext.ap_log.log_handlers.DatabaseHandler
formatter = generic
level = NOTSET
kwargs={"db_uri": "postgresql://ckan_default:pass@localhost/master"}
```

3. The logging handler must be also included in `[handlers]` section.
4. The logging handler must be also included in `[handlers]` section.
```
[handlers]
keys = console, dbHandler
```
4. The last thing you need to do is to add our handler to a logger you need. For example, if you want to log only `ckan` logs, do this:
5. The last thing you need to do is to add our handler to a logger you need. For example, if you want to log only `ckan` logs, do this:
```
[logger_ckan]
level = INFO
Expand Down
Empty file added ckanext/ap_log/__init__.py
Empty file.
21 changes: 21 additions & 0 deletions ckanext/ap_log/col_renderers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from __future__ import annotations

import logging
from typing import Any, Callable

from ckanext.collection.types import BaseSerializer

from ckanext.toolbelt.decorators import Collector

from ckanext.ap_main.types import ColRenderer

renderer: Collector[ColRenderer]
get_renderers: Callable[[], dict[str, ColRenderer]]
renderer, get_renderers = Collector().split()


@renderer
def log_level(
value: Any, options: dict[str, Any], name: str, record: Any, self: BaseSerializer
) -> str:
return logging.getLevelName(value)
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,14 @@
)
from ckanext.collection.utils import Filters, ModelData

from ckanext.ap_main.model import ApLogs
from ckanext.ap_main.collection.base import (
ApCollection,
MultiSelectFilter,
GlobalAction,
)

from ckanext.ap_log.model import ApLogs


class DbLogCollection(ApCollection):
ColumnsFactory = ApCollection.ColumnsFactory.with_attributes(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

from ckan.plugins import toolkit as tk

from ckanext.ap_main.model import ApLogs
from ckanext.ap_log.model import ApLogs

log = logging.getLogger(__name__)

Expand Down
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ script_location = %(here)s
# sourceless = false

# version location specification; this defaults
# to /home/berry/projects/master/ckanext-admin-panel/ckanext/admin_panel/migration/admin_panel/versions. When using multiple version
# to /home/berry/projects/master/ckanext-admin-panel/ckanext/ap_log/migration/admin_panel_log/versions. When using multiple version
# directories, initial revisions must be specified with --version-path
# version_locations = %(here)s/bar %(here)s/bat /home/berry/projects/master/ckanext-admin-panel/ckanext/admin_panel/migration/admin_panel/versions
# version_locations = %(here)s/bar %(here)s/bat /home/berry/projects/master/ckanext-admin-panel/ckanext/ap_log/migration/admin_panel_log/versions

# the output encoding used when revision files
# are written from script.py.mako
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
# -*- coding: utf-8 -*-

from __future__ import with_statement

import os
from logging.config import fileConfig

from alembic import context
from sqlalchemy import engine_from_config, pool
from logging.config import fileConfig

import os

# this is the Alembic Config object, which provides
# access to the values within the .ini file in use.
Expand Down Expand Up @@ -43,12 +42,10 @@ def run_migrations_offline():
"""

url = config.get_main_option("sqlalchemy.url")
url = config.get_main_option(u"sqlalchemy.url")
context.configure(
url=url,
target_metadata=target_metadata,
literal_binds=True,
version_table="{}_alembic_version".format(name),
url=url, target_metadata=target_metadata, literal_binds=True,
version_table=u'{}_alembic_version'.format(name)
)

with context.begin_transaction():
Expand All @@ -64,15 +61,14 @@ def run_migrations_online():
"""
connectable = engine_from_config(
config.get_section(config.config_ini_section),
prefix="sqlalchemy.",
poolclass=pool.NullPool,
)
prefix=u'sqlalchemy.',
poolclass=pool.NullPool)

with connectable.connect() as connection:
context.configure(
connection=connection,
target_metadata=target_metadata,
version_table="{}_alembic_version".format(name),
version_table=u'{}_alembic_version'.format(name)
)

with context.begin_transaction():
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
"""Add ApLogs table
"""Init table
Revision ID: 65d431520aa2
Revision ID: fe11724f1867
Revises:
Create Date: 2023-08-21 10:18:49.128929
Create Date: 2024-03-11 13:20:05.331015
"""
import sqlalchemy as sa
from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision = "65d431520aa2"
revision = 'fe11724f1867'
down_revision = None
branch_labels = None
depends_on = None
Expand Down
File renamed without changes.
54 changes: 54 additions & 0 deletions ckanext/ap_log/plugin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
from __future__ import annotations

import ckan.plugins as p
import ckan.plugins.toolkit as tk

from ckanext.collection.interfaces import ICollection, CollectionFactory
from ckanext.ap_main.interfaces import IAdminPanel
import ckanext.ap_main.types as ap_types

from ckanext.ap_log.col_renderers import get_renderers
from ckanext.ap_log import collection


@tk.blanket.blueprints
class AdminPanelLogPlugin(p.SingletonPlugin):
p.implements(p.IConfigurer)
p.implements(IAdminPanel, inherit=True)
p.implements(ICollection, inherit=True)

# IConfigurer

def update_config(self, config_: tk.CKANConfig):
tk.add_template_directory(config_, "templates")
tk.add_public_directory(config_, "public")
tk.add_resource("assets", "ap_log")

# IAdminPanel

def get_col_renderers(self) -> dict[str, ap_types.ColRenderer]:
return get_renderers()

def register_toolbar_button(
self, toolbar_buttons_list: list[ap_types.ToolbarButton]
) -> list[ap_types.ToolbarButton]:
"""Extension will receive the list of toolbar button objects."""

for button in toolbar_buttons_list:
if button.get("label") == "Reports":
button.setdefault("subitems", [])

button["subitems"].append( # type: ignore
ap_types.ToolbarButton(
label=tk._("Logs"),
url=tk.url_for("ap_log.list"),
)
)

return toolbar_buttons_list

# ICollection
def get_collection_factories(self) -> dict[str, CollectionFactory]:
return {
"ap-logs": collection.DbLogCollection,
}
Empty file.
File renamed without changes.
21 changes: 9 additions & 12 deletions ckanext/ap_main/views/reports.py → ckanext/ap_log/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,21 @@
from ckan.logic import parse_params

from ckanext.collection.shared import get_collection
from ckanext.ap_main.model import ApLogs
from ckanext.ap_main.utils import ap_before_request

ap_report = Blueprint("ap_report", __name__, url_prefix="/admin-panel")
ap_report.before_request(ap_before_request)
from ckanext.ap_log.model import ApLogs


ap_log = Blueprint("ap_log", __name__, url_prefix="/admin-panel")
ap_log.before_request(ap_before_request)


class ReportLogsView(MethodView):
def get(self) -> Union[str, Response]:
if not ApLogs.table_initialized():
return tk.render(
"admin_panel/config/reports/logs_disabled.html",
)
return tk.render("ap_log/logs_disabled.html")

return tk.render(
"admin_panel/config/reports/logs.html",
extra_vars=self._prepare_data_dict(),
)
return tk.render("ap_log/logs.html", extra_vars=self._prepare_data_dict())

def _prepare_data_dict(self) -> dict[str, Any]:
return {
Expand All @@ -38,7 +35,7 @@ def post(self) -> Response:
ApLogs.clear_logs()
tk.h.flash_success(tk._("Logs have been cleared."))

return tk.redirect_to("ap_report.logs")
return tk.redirect_to("ap_log.list")


ap_report.add_url_rule("/reports/logs", view_func=ReportLogsView.as_view("logs"))
ap_log.add_url_rule("/reports/logs", view_func=ReportLogsView.as_view("list"))
2 changes: 0 additions & 2 deletions ckanext/ap_main/collection/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
from .content import ContentCollection
from .user import UserCollection
from .report import DbLogCollection

__all__ = [
"ContentCollection",
"UserCollection",
"DbLogCollection",
]
7 changes: 1 addition & 6 deletions ckanext/ap_main/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,7 @@ def get_toolbar_structure() -> list[ToolbarButton]:
ToolbarButton(
label=tk._("Reports"),
icon="fa fa-chart-bar",
subitems=[
ToolbarButton(
label=tk._("Recent log messages"),
url=tk.url_for("ap_report.logs"),
)
],
subitems=[],
),
ToolbarButton(
icon="fa fa-gavel",
Expand Down
3 changes: 1 addition & 2 deletions ckanext/ap_main/plugin.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from __future__ import annotations

from typing import Any, Callable, Literal
from typing import Any, Callable

import ckan.plugins as p
import ckan.plugins.toolkit as tk
Expand Down Expand Up @@ -46,7 +46,6 @@ def get_collection_factories(self) -> dict[str, CollectionFactory]:
return {
"ap-content": collection.ContentCollection,
"ap-user": collection.UserCollection,
"ap-logs": collection.DbLogCollection,
}

# ISignal
Expand Down
2 changes: 0 additions & 2 deletions ckanext/ap_main/views/__init__.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
from ckanext.ap_main.views.basic import ap_basic
from ckanext.ap_main.views.config import ap_config_list
from ckanext.ap_main.views.content import ap_content
from ckanext.ap_main.views.reports import ap_report
from ckanext.ap_main.views.user import ap_user

__all__ = [
"ap_basic",
"ap_config_list",
"ap_user",
"ap_report",
"ap_content",
]
1 change: 1 addition & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ include_package_data = True
[options.entry_points]
ckan.plugins =
admin_panel = ckanext.ap_main.plugin:AdminPanelPlugin
admin_panel_log = ckanext.ap_log.plugin:AdminPanelLogPlugin
admin_panel_cron = ckanext.ap_cron.plugin:AdminPanelCronPlugin
admin_panel_support = ckanext.ap_support.plugin:AdminPanelSupportPlugin
admin_panel_example = ckanext.ap_example.plugin:AdminPanelExamplePlugin
Expand Down

0 comments on commit 951cd30

Please sign in to comment.