Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
29 changes: 28 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
- [InfluxDB 3](#influxdb-3)
- [Aggregated Dashboards (Optional)](#aggregated-dashboards-optional)
- [Other configuration](#other-configuration)
- [Logging](#logging)
- [Development](#development)
- [Development Environment](#development-environment)
- [Setup](#setup)
Expand Down Expand Up @@ -205,7 +206,33 @@ Also, following environment valuables can be used to configure the service behav
|---|---|---|
|TOPIC_MODEL||Specifies the name or path for the topic model. If the model is specified by name, it will be downloaded from the [Huggingface]( https://huggingface.co/). When unset or set to an empty string, the topic classification feature is disabled.|
|TOPIC_EMBEDDINGS_MODEL||Specifies the name or path for the embeddings model used with the topic model. If the model is specified by name, it will be downloaded from the [Huggingface]( https://huggingface.co/). When unset or set to an empty string, the name will be used from the topic model config.|
|LOG_LEVEL|INFO|The server logging level. Use DEBUG for dev purposes and INFO in prod|
|LOG_LEVEL|INFO|Application log level. Use DEBUG for dev purposes and INFO in prod|

### Logging

Logging is provided by the DIAL SDK. The `LOG_LEVEL` variable sets the severity threshold for the application's own logs (`INFO` by default; use `DEBUG` for development).

By default logs are emitted as human-readable text.
Set `DIAL_SDK_LOG_FORMAT=json` for structured JSON logging.
The format is controlled by `DIAL_SDK_TEXT_LOG_FORMAT` / `DIAL_SDK_JSON_LOG_FORMAT` (both optional),
which use Python's `%`-style [logging attributes](https://docs.python.org/3/library/logging.html#logrecord-attributes)
and default to the values shown below.

Text logging (default):

```txt
DIAL_SDK_LOG_FORMAT=text
DIAL_SDK_TEXT_LOG_FORMAT='%(levelprefix)s | %(asctime)s | %(name)s | %(process)d | %(message)s'
```

Structured JSON logging:

```txt
DIAL_SDK_LOG_FORMAT=json
DIAL_SDK_JSON_LOG_FORMAT='{"level": "%(levelname)s", "time": "%(asctime)s", "logger": "%(name)s", "process": "%(process)d", "message": "%(message)s"}'
```

See the [full logging documentation](https://github.com/epam/ai-dial-sdk/blob/0.38.0/docs/logging.md) for details.

## Development

Expand Down
2 changes: 2 additions & 0 deletions aidial_analytics_realtime/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ async def lifespan(app: FastAPI):

init_telemetry(app, TelemetryConfig())

# NOTE: configuring loggers after the DIAL telemetry is initialized,
# because it may have configured the root logger on its own.
configure_loggers()

check_deprecations()
Expand Down
44 changes: 10 additions & 34 deletions aidial_analytics_realtime/utils/logging.py
Original file line number Diff line number Diff line change
@@ -1,52 +1,28 @@
import logging
import os
import sys
from contextvars import ContextVar

from uvicorn.logging import DefaultFormatter
from aidial_sdk import LogConfig, configure_root_logger

app_logger = logging.getLogger("app")
LOG_LEVEL = os.getenv("LOG_LEVEL", "INFO")


def configure_loggers():
# Delegate uvicorn logs to the root logger
# to achieve uniform log formatting
for name, log in logging.getLogger().manager.loggerDict.items():
if isinstance(log, logging.Logger) and name.startswith("uvicorn"):
log.handlers = []
log.propagate = True
# Delegate to the SDK to install a uniformly formatted root logger
# handler and to route uvicorn logs through it, preserving this
# repo's original text log format.
configure_root_logger(
LogConfig(
text_format="%(levelprefix)s | %(asctime)s | %(process)d | %(name)s | %(message)s" # noqa: E501
)
)

# Setting log levels for the analytics application
app_logger.setLevel(LOG_LEVEL)

# Configuring the root logger
root = logging.getLogger()

stderr_handler = next(
(
handler
for handler in root.handlers
if isinstance(handler, logging.StreamHandler)
and handler.stream == sys.stderr
),
None,
)

# Do not override the existing stderr handlers
# if they are already configured
if stderr_handler is None:
formatter = DefaultFormatter(
fmt="%(levelprefix)s | %(asctime)s | %(process)d | %(name)s | %(message)s", # noqa: E501
use_colors=True,
)

handler = logging.StreamHandler(sys.stderr)
handler.setFormatter(formatter)
for handler in logging.getLogger().handlers:
handler.addFilter(_PrefixFilter())
root.addHandler(handler)
else:
stderr_handler.addFilter(_PrefixFilter())


_logger_prefix: ContextVar[str] = ContextVar("_logger_prefix", default="")
Expand Down
10 changes: 5 additions & 5 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ bertopic = "^0.15.0"
python-dotenv = "^1.2.2"
python-dateutil = "^2.8.2"
pydantic = "2.7.0"
aidial-sdk = { version = "0.33.1", extras = ["telemetry"] }
aidial-sdk = { version = "0.38.0", extras = ["telemetry"] }

# Indirect dependencies
torch = [
Expand Down
Loading