Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Per Tenant Logging - Complete Implementation #2425

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
bd77c9b
initial commit
shaangill025 Aug 12, 2023
a45f806
incomplete test changes
shaangill025 Aug 12, 2023
c57eaf6
unit test changes
shaangill025 Aug 16, 2023
cb1cb82
unit tests fix
shaangill025 Aug 17, 2023
214803f
fmt fix
shaangill025 Aug 17, 2023
85a52f8
optimization + demo updates
shaangill025 Aug 22, 2023
c87762e
new logging optimization + cleanup
shaangill025 Aug 23, 2023
adda4e7
rework based upon feedback
shaangill025 Aug 29, 2023
9a6e9b7
update logging functions docstring
shaangill025 Aug 29, 2023
8e9b0f2
WIP - rework with contextvar
shaangill025 Sep 7, 2023
6bdc111
cleanup from previous work
shaangill025 Sep 8, 2023
202bf79
remove redundant code
shaangill025 Sep 8, 2023
0daf2cb
test fix
shaangill025 Sep 9, 2023
2d7cfb6
retrigger checks
shaangill025 Sep 9, 2023
5f1c374
update test
shaangill025 Sep 11, 2023
46b8083
optimization and test updates
shaangill025 Sep 16, 2023
f19e289
Merge branch 'main' of https://github.com/hyperledger/aries-cloudagen…
shaangill025 Sep 16, 2023
cffa9ce
doc update
shaangill025 Sep 18, 2023
fa9ad93
Merge branch 'main' into per_tenant_logging
shaangill025 Sep 18, 2023
e6c3fe8
Merge branch 'main' into per_tenant_logging
shaangill025 Oct 4, 2023
2c94365
Merge branch 'main' into per_tenant_logging
swcurran Oct 5, 2023
8d8859f
updates based on feedback
shaangill025 Oct 16, 2023
834cb62
Merge branch 'main' of https://github.com/hyperledger/aries-cloudagen…
shaangill025 Oct 16, 2023
1fd8587
Merge branch 'per_tenant_logging' of https://github.com/shaangill025/…
shaangill025 Oct 16, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 68 additions & 8 deletions Logging.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,29 +12,27 @@ Other log levels fall back to `WARNING`.

* `--log-level` - The log level to log on std out.
* `--log-file` - Path to a file to log to.
* `--log-handler-config` - Specifies `when`, `interval`, `backupCount` for the `TimedRotatingFileMultiProcessHandler`. These 3 attributes are passed as a `;` seperated string. For example, `when` of d (days), `interval` of 7 and `backupCount` of 1 will be passed as `D;7;1`. Note: `backupCount` of 0 will mean all backup log files will be retained and not deleted at all. More details about these attributes can be found [here](https://docs.python.org/3/library/logging.handlers.html#timedrotatingfilehandler). `TimedRotatingFileMultiProcessHandler` supports the ability to cleanup logs by time and mantain backup logs and a custom JSON formatter for logs.
* `--log-fmt-pattern` - Specifies logging.Formatter pattern to override default patterns.
* `--log-json-fmt` - Specifies whether to use JSON logging formatter or text logging formatter. Defaults to `False`.
* `--log-config` - Specifies a custom logging configuration file


Example:

```sh
./bin/aca-py start --log-level debug --log-file acapy.log --log-handler-config "d;7;1" --log-fmt-pattern "%(asctime)s [%(did)s] %(filename)s %(lineno)d %(message)s" --log-json-fmt
./bin/aca-py start --log-level debug --log-file acapy.log --log-config aries_cloudagent.config:default_per_tenant_logging_config.ini

./bin/aca-py start --log-level debug --log-file acapy.log --log-config ./aries_cloudagent/config/default_per_tenant_logging_config.yml
```

## Environment Variables

The log level can be configured using the environment variable `ACAPY_LOG_LEVEL`.
The log file can be set by `ACAPY_LOG_FILE`.
The log config can be set by `ACAPY_LOG_CONFIG`.
The log rotating file handler config can be set by `ACAPY_LOG_HANDLER_CONFIG`.
The log formatter pattern can be set by `ACAPY_LOG_FMT_PATTERN`.
The log json formatter flag can be set by `ACAPY_LOG_JSON_FMT`.

Example:

```sh
ACAPY_LOG_LEVEL=info ACAPY_LOG_FILE=./acapy.log ACAPY_LOG_CONFIG=./acapy_log.ini ACAPY_LOG_HANDLER_CONFIG="d;7;1" ./bin/aca-py start
ACAPY_LOG_LEVEL=info ACAPY_LOG_FILE=./acapy.log ACAPY_LOG_CONFIG=./acapy_log.ini ./bin/aca-py start
```

## Acapy Config File
Expand All @@ -52,7 +50,69 @@ Both parameters are independent of the log level, which means:
Also if log-level is set to WARNING, connections and presentations will be logged like in debug log level.

## Log config file
The path to config file is provided via `--log-config`.

Find an example in [default_logging_config.ini](aries_cloudagent/config/default_logging_config.ini).

You can find more detail description in the [logging documentation](https://docs.python.org/3/howto/logging.html#configuring-logging).


For per tenant logging, find an example in [default_per_tenant_logging_config.ini](aries_cloudagent/config/default_per_tenant_logging_config.ini), which sets up `TimedRotatingFileMultiProcessHandler` and `StreamHandler` handlers. Custom `TimedRotatingFileMultiProcessHandler` handler supports the ability to cleanup logs by time and mantain backup logs and a custom JSON formatter for logs. The arguments for it such as `file name`, `when`, `interval` and `backupCount` can be passed as `args=('acapy.log', 'd', 7, 1,)` [also shown below]. Note: `backupCount` of 0 will mean all backup log files will be retained and not deleted at all. More details about these attributes can be found [here](https://docs.python.org/3/library/logging.handlers.html#timedrotatingfilehandler)

```
[loggers]
keys=root

[handlers]
keys=stream_handler, timed_file_handler

[formatters]
keys=formatter

[logger_root]
level=ERROR
handlers=stream_handler, timed_file_handler

[handler_stream_handler]
class=StreamHandler
level=DEBUG
formatter=formatter
args=(sys.stderr,)

[handler_timed_file_handler]
class=logging.handlers.TimedRotatingFileMultiProcessHandler
level=DEBUG
formatter=formatter
args=('acapy.log', 'd', 7, 1,)

[formatter_formatter]
format=%(asctime)s %(wallet_id)s %(levelname)s %(pathname)s:%(lineno)d %(message)s
```

For `DictConfig` [`dict` logging config file], find an example in [default_per_tenant_logging_config.yml](aries_cloudagent/config/default_per_tenant_logging_config.yml) with same attributes as `default_per_tenant_logging_config.ini` file.

```
version: 1
formatters:
default:
format: '%(asctime)s %(wallet_id)s %(levelname)s %(pathname)s:%(lineno)d %(message)s'
handlers:
console:
class: logging.StreamHandler
level: DEBUG
formatter: default
stream: ext://sys.stderr
rotating_file:
class: logging.handlers.TimedRotatingFileMultiProcessHandler
level: DEBUG
filename: 'acapy.log'
when: 'd'
interval: 7
backupCount: 1
formatter: default
root:
level: INFO
handlers:
- console
- rotating_file
```
6 changes: 6 additions & 0 deletions aries_cloudagent/admin/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from marshmallow import fields

from ..config.injection_context import InjectionContext
from ..config.logging import context_wallet_id
from ..core.event_bus import Event, EventBus
from ..core.plugin_registry import PluginRegistry
from ..core.profile import Profile
Expand Down Expand Up @@ -407,6 +408,11 @@ async def setup_context(request: web.Request, handler):
) = self.multitenant_manager.get_wallet_details_from_token(
token=token
)
try:
context_wallet_id.get()
except LookupError:
wallet_id = profile.settings.get("wallet.id")
context_wallet_id.set(wallet_id)
meta_data = {
"wallet_id": walletid,
"wallet_key": walletkey,
Expand Down
63 changes: 0 additions & 63 deletions aries_cloudagent/config/argparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -1013,46 +1013,6 @@ def add_arguments(self, parser: ArgumentParser):
"('debug', 'info', 'warning', 'error', 'critical')"
),
)
parser.add_argument(
"--log-handler-config",
dest="log_handler_config",
type=str,
metavar="<log-handler-config>",
default=None,
env_var="ACAPY_LOG_HANDLER_CONFIG",
help=(
"Specifies when, interval, backupCount for the "
"TimedRotatingFileHandler. These attributes are "
"passed as a ; seperated string. For example, "
"when of D (days), interval of 7 and backupCount "
"of 1 will be passed as 'D;7;1'. Note: "
"backupCount of 0 will mean all backup log files "
"will be retained and not deleted at all."
),
)
parser.add_argument(
"--log-fmt-pattern",
dest="log_fmt_pattern",
type=str,
metavar="<log-fmt-pattern>",
default=None,
env_var="ACAPY_LOG_FMT_PATTERN",
help=(
"Specifies logging formatter pattern as string. Examples are included "
"in 'Logging.md'. For information regarding different attributes "
"supported in the pattern, please look at "
"https://docs.python.org/3/library/logging.html#logrecord-attributes."
),
)
parser.add_argument(
"--log-json-fmt",
action="store_true",
env_var="ACAPY_LOG_JSON_FMT",
help=(
"Specifies whether to use JSON logging formatter or "
"text logging formatter."
),
)

def get_settings(self, args: Namespace) -> dict:
"""Extract logging settings."""
Expand All @@ -1063,29 +1023,6 @@ def get_settings(self, args: Namespace) -> dict:
settings["log.file"] = args.log_file
if args.log_level:
settings["log.level"] = args.log_level
if args.log_handler_config:
try:
handler_config_attribs = (args.log_handler_config).split(";")
settings["log.handler_when"] = handler_config_attribs[0]
settings["log.handler_interval"] = int(handler_config_attribs[1])
settings["log.handler_bakcount"] = int(handler_config_attribs[2])
except IndexError:
raise ArgsParseError(
"With --log-handler-config, the provided argument must be "
"in 'when;interval;backupCount' format. Each of the 3 "
"attributes for TimedRotatingFileHandler must be specified."
)
except ValueError:
raise ArgsParseError(
"With --log-handler-config, 'interval' and 'backupCount' "
"should be a number [int]"
)
if args.log_fmt_pattern:
settings["log.fmt_pattern"] = args.log_fmt_pattern
if args.log_json_fmt:
settings["log.json_fmt"] = True
else:
settings["log.json_fmt"] = False
return settings


Expand Down
27 changes: 27 additions & 0 deletions aries_cloudagent/config/default_per_tenant_logging_config.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
[loggers]
keys=root

[handlers]
keys=stream_handler, timed_file_handler

[formatters]
keys=formatter

[logger_root]
level=ERROR
handlers=stream_handler, timed_file_handler

[handler_stream_handler]
class=StreamHandler
level=DEBUG
formatter=formatter
args=(sys.stderr,)

[handler_timed_file_handler]
class=logging.handlers.TimedRotatingFileMultiProcessHandler
level=DEBUG
formatter=formatter
args=('acapy.log', 'd', 7, 1,)

[formatter_formatter]
format=%(asctime)s %(wallet_id)s %(levelname)s %(pathname)s:%(lineno)d %(message)s
23 changes: 23 additions & 0 deletions aries_cloudagent/config/default_per_tenant_logging_config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
version: 1
formatters:
default:
format: '%(asctime)s %(wallet_id)s %(levelname)s %(pathname)s:%(lineno)d %(message)s'
handlers:
console:
class: logging.StreamHandler
level: DEBUG
formatter: default
stream: ext://sys.stderr
rotating_file:
class: logging.handlers.TimedRotatingFileMultiProcessHandler
level: DEBUG
filename: 'acapy.log'
when: 'd'
interval: 7
backupCount: 1
formatter: default
root:
level: INFO
handlers:
- console
- rotating_file
Loading