Skip to content

Commit

Permalink
Merge pull request #1653 from pbiering/collection-cache-logging
Browse files Browse the repository at this point in the history
Collection cache logging
  • Loading branch information
pbiering authored Dec 14, 2024
2 parents 05b8172 + f7d6f64 commit 4d04c85
Show file tree
Hide file tree
Showing 9 changed files with 33 additions and 5 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
* Improve: log important module versions on startup
* Improve: auth.ldap config shown on startup, terminate in case no password is supplied for bind user
* Add: option [auth] uc_username for uppercase conversion (similar to existing lc_username)
* Add: option [debug] storage_cache_action for conditional logging

## 3.3.1

Expand Down
10 changes: 8 additions & 2 deletions DOCUMENTATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -1158,18 +1158,24 @@ Log request on level=debug

Default: `False`

##### response_content_on_debug = True
##### response_content_on_debug

Log response on level=debug

Default: `False`

##### rights_rule_doesnt_match_on_debug = True
##### rights_rule_doesnt_match_on_debug

Log rights rule which doesn't match on level=debug

Default: `False`

##### #storage_cache_actions

Log storage cache actions

Default: `False`

#### headers

In this section additional HTTP headers that are sent to clients can be
Expand Down
2 changes: 2 additions & 0 deletions config
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,8 @@
# Log rights rule which doesn't match on level=debug
#rights_rule_doesnt_match_on_debug = False

# Log storage cache actions
#storage_cache_actions = False

[headers]

Expand Down
4 changes: 4 additions & 0 deletions radicale/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,10 @@ def json_str(value: Any) -> dict:
"value": "False",
"help": "log rights rules which doesn't match on level=debug",
"type": bool}),
("storage_cache_actions", {
"value": "False",
"help": "log storage cache action on level=debug",
"type": bool}),
("mask_passwords", {
"value": "True",
"help": "mask passwords in logs",
Expand Down
1 change: 1 addition & 0 deletions radicale/storage/multifilesystem/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ def __init__(self, configuration: config.Configuration) -> None:
logger.info("storage cache subfolder usage for 'item': %s", self._use_cache_subfolder_for_item)
logger.info("storage cache subfolder usage for 'history': %s", self._use_cache_subfolder_for_history)
logger.info("storage cache subfolder usage for 'sync-token': %s", self._use_cache_subfolder_for_synctoken)
logger.debug("storage cache action logging: %s", self._debug_cache_actions)
if self._use_cache_subfolder_for_item is True or self._use_cache_subfolder_for_history is True or self._use_cache_subfolder_for_synctoken is True:
logger.info("storage cache subfolder: %r", self._get_collection_cache_folder())
self._makedirs_synced(self._get_collection_cache_folder())
Expand Down
3 changes: 3 additions & 0 deletions radicale/storage/multifilesystem/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ class StorageBase(storage.BaseStorage):
_use_cache_subfolder_for_item: bool
_use_cache_subfolder_for_history: bool
_use_cache_subfolder_for_synctoken: bool
_debug_cache_actions: bool
_folder_umask: str
_config_umask: int

Expand All @@ -93,6 +94,8 @@ def __init__(self, configuration: config.Configuration) -> None:
"storage", "use_cache_subfolder_for_synctoken")
self._folder_umask = configuration.get(
"storage", "folder_umask")
self._debug_cache_actions = configuration.get(
"logging", "storage_cache_actions")

def _get_collection_root_folder(self) -> str:
return os.path.join(self._filesystem_folder, "collection-root")
Expand Down
5 changes: 4 additions & 1 deletion radicale/storage/multifilesystem/create_collection.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# This file is part of Radicale - CalDAV and CardDAV server
# Copyright © 2014 Jean-Marc Martins
# Copyright © 2012-2017 Guillaume Ayoub
# Copyright © 2017-2018 Unrud <unrud@outlook.com>
# Copyright © 2017-2021 Unrud <unrud@outlook.com>
# Copyright © 2024-2024 Peter Bieringer <pb@bieringer.de>
#
# This library is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
Expand All @@ -22,6 +23,7 @@

import radicale.item as radicale_item
from radicale import pathutils
from radicale.log import logger
from radicale.storage import multifilesystem
from radicale.storage.multifilesystem.base import StorageBase

Expand All @@ -36,6 +38,7 @@ def create_collection(self, href: str,
# Path should already be sanitized
sane_path = pathutils.strip_path(href)
filesystem_path = pathutils.path_to_filesystem(folder, sane_path)
logger.debug("Create collection: %r" % filesystem_path)

if not props:
self._makedirs_synced(filesystem_path)
Expand Down
2 changes: 2 additions & 0 deletions radicale/storage/multifilesystem/get.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ def _get(self, href: str, verify_href: bool = True
# The hash of the component in the file system. This is used to check,
# if the entry in the cache is still valid.
cache_hash = self._item_cache_hash(raw_text)
if self._storage._debug_cache_actions is True:
logger.debug("Check cache for: %r with hash %r", path, cache_hash)
cache_content = self._load_item_cache(href, cache_hash)
if cache_content is None:
with self._acquire_cache_lock("item"):
Expand Down
10 changes: 8 additions & 2 deletions radicale/storage/multifilesystem/upload.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

import radicale.item as radicale_item
from radicale import pathutils
from radicale.log import logger
from radicale.storage.multifilesystem.base import CollectionBase
from radicale.storage.multifilesystem.cache import CollectionPartCache
from radicale.storage.multifilesystem.get import CollectionPartGet
Expand All @@ -38,12 +39,14 @@ def upload(self, href: str, item: radicale_item.Item
) -> radicale_item.Item:
if not pathutils.is_safe_filesystem_path_component(href):
raise pathutils.UnsafePathError(href)
path = pathutils.path_to_filesystem(self._filesystem_path, href)
try:
self._store_item_cache(href, item)
cache_hash = self._item_cache_hash(item.serialize().encode(self._encoding))
logger.debug("Store cache for: %r with hash %r", path, cache_hash)
self._store_item_cache(href, item, cache_hash)
except Exception as e:
raise ValueError("Failed to store item %r in collection %r: %s" %
(href, self.path, e)) from e
path = pathutils.path_to_filesystem(self._filesystem_path, href)
# TODO: better fix for "mypy"
with self._atomic_write(path, newline="") as fo: # type: ignore
f = cast(TextIO, fo)
Expand Down Expand Up @@ -80,6 +83,7 @@ def get_safe_free_hrefs(uid: str) -> Iterator[str]:
self._storage._makedirs_synced(cache_folder)
for item in items:
uid = item.uid
logger.debug("Store item from list with uid: '%s'" % uid)
try:
cache_content = self._item_cache_content(item)
except Exception as e:
Expand All @@ -105,6 +109,8 @@ def get_safe_free_hrefs(uid: str) -> Iterator[str]:
f.flush()
self._storage._fsync(f)
with open(os.path.join(cache_folder, href), "wb") as fb:
cache_hash = self._item_cache_hash(item.serialize().encode(self._encoding))
logger.debug("Store cache for: %r with hash %r", fb.name, cache_hash)
pickle.dump(cache_content, fb)
fb.flush()
self._storage._fsync(fb)
Expand Down

0 comments on commit 4d04c85

Please sign in to comment.