Skip to content

Commit

Permalink
Merge 97eef6a into 0bf7c13
Browse files Browse the repository at this point in the history
  • Loading branch information
alvassin committed Apr 11, 2023
2 parents 0bf7c13 + 97eef6a commit fb38c68
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 42 deletions.
8 changes: 8 additions & 0 deletions aiomisc/entrypoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ class Entrypoint:
DEFAULT_LOG_FORMAT: str = os.getenv(
"AIOMISC_LOG_FORMAT", LogFormat.default(),
)
DEFAULT_LOG_DATE_FORMAT: Optional[str] = os.getenv(
"AIOMISC_LOG_DATE_FORMAT"
)

DEFAULT_AIOMISC_DEBUG: bool = _get_env_bool("AIOMISC_DEBUG", "0")
DEFAULT_AIOMISC_LOG_CONFIG: bool = _get_env_bool(
Expand Down Expand Up @@ -80,6 +83,7 @@ async def _start(self) -> None:
basic_config(
level=self.log_level,
log_format=self.log_format,
date_format=self.log_date_format,
buffered=self.log_buffering,
loop=self.loop,
buffer_size=self.log_buffer_size,
Expand Down Expand Up @@ -108,6 +112,7 @@ def __init__(
log_format: Union[str, LogFormat] = DEFAULT_LOG_FORMAT,
log_buffering: bool = DEFAULT_AIOMISC_BUFFERING,
log_buffer_size: int = DEFAULT_AIOMISC_BUFFER_SIZE,
log_date_format: Optional[str] = DEFAULT_LOG_DATE_FORMAT,
log_flush_interval: float = DEFAULT_AIOMISC_LOG_FLUSH,
log_config: bool = DEFAULT_AIOMISC_LOG_CONFIG,
policy: asyncio.AbstractEventLoopPolicy = event_loop_policy,
Expand Down Expand Up @@ -138,6 +143,7 @@ def __init__(
self.log_buffer_size = log_buffer_size
self.log_buffering = log_buffering
self.log_config = log_config
self.log_date_format = log_date_format
self.log_flush_interval = log_flush_interval
self.log_format = log_format
self.log_level = log_level
Expand All @@ -155,6 +161,7 @@ def __init__(
aiomisc_log.basic_config(
level=self.log_level,
log_format=self.log_format,
date_format=log_date_format
)

if self._loop is not None:
Expand Down Expand Up @@ -206,6 +213,7 @@ def __exit__(
basic_config(
level=self.log_level,
log_format=self.log_format,
date_format=self.log_date_format,
buffered=False,
)

Expand Down
16 changes: 10 additions & 6 deletions docs/source/entrypoint.rst
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ Module support configuration from environment variables:

* `AIOMISC_LOG_LEVEL` - default logging level
* `AIOMISC_LOG_FORMAT` - default log format
* `AIOMISC_LOG_DATE_FORMAT` - default logging date format
* `AIOMISC_LOG_CONFIG` - should logging be configured
* `AIOMISC_LOG_FLUSH` - interval between logs flushing from buffer
* `AIOMISC_LOG_BUFFERING` - should logging be buffered
Expand Down Expand Up @@ -154,8 +155,8 @@ but handle ``Service``'s and other ``entrypoint``'s kwargs.
Logging configuration
=====================

``entrypoint`` accepts a specific set of formats in which logs will be
written to stderr.
``entrypoint`` accepts ``log_format`` argument with a specific set of formats,
in which logs will be written to stderr:

* ``stream`` - Python's default logging handler
* ``color`` - logging with `colorlog` module
Expand All @@ -164,13 +165,16 @@ written to stderr.
* ``plain`` - just log messages, without date or level info
* ``journald`` - available only when `logging-journald` module
has been installed.
* ``rich``/``rich_tb` - available only when `rich` module has been installed.
* ``rich``/``rich_tb`` - available only when `rich` module has been installed.
``rich_tb`` it's the same as ``rich`` but with fully expanded tracebacks.

Additionally, you can specify log level using ``log_level`` argument and date
format using ``log_date_format`` parameters.

An ``entrypoint`` will call ``aiomisc.log.basic_config`` function implicitly
using passed ``log_level=`` and ``log_format=`` parameters.
Alternatively you can call ``aiomisc.log.basic_config`` function manually
passing it already created eventloop.
using passed ``log_*`` parameters. Alternatively you can call
``aiomisc.log.basic_config`` function manually passing it already created
eventloop.

However, you can configure logging earlier using ``aiomisc_log.basic_config``,
but you will lose log buffering and flushing in a separate thread.
Expand Down
8 changes: 7 additions & 1 deletion docs/source/locale/ru/LC_MESSAGES/api/aiomisc_log.po
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: aiomisc 16.1.16\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-02-15 22:21+0300\n"
"POT-Creation-Date: 2023-04-11 22:10+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
Expand Down Expand Up @@ -107,3 +107,9 @@ msgstr "Модуль ``aiomisc_log.formatter.rich.py``"
#: ../../source/api/aiomisc_log.rst:34
msgid "``aiomisc_log.enum`` module"
msgstr "Модуль ``aiomisc_log.enum``"

#: aiomisc_log.enum.DateFormat:1 aiomisc_log.enum.LogFormat:1
#: aiomisc_log.enum.LogLevel:1 of
msgid "An enumeration."
msgstr ""

80 changes: 46 additions & 34 deletions docs/source/locale/ru/LC_MESSAGES/entrypoint.po
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: 14\n"
"Report-Msgid-Bugs-To: me@mosquito.su\n"
"POT-Creation-Date: 2023-02-16 09:55+0300\n"
"POT-Creation-Date: 2023-04-11 21:29+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Dmitry Orlov <me@mosquito.su>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
Expand Down Expand Up @@ -209,30 +209,34 @@ msgid "`AIOMISC_LOG_FORMAT` - default log format"
msgstr "`AIOMISC_LOG_FORMAT` - формат логирования по умолчанию"

#: ../../source/entrypoint.rst:125
msgid "`AIOMISC_LOG_DATE_FORMAT` - default logging date format"
msgstr "`AIOMISC_LOG_DATE_FORMAT` - формат дат в логах по умолчанию"

#: ../../source/entrypoint.rst:126
msgid "`AIOMISC_LOG_CONFIG` - should logging be configured"
msgstr "`AIOMISC_LOG_CONFIG` - следует ли настраивать логирование"

#: ../../source/entrypoint.rst:126
#: ../../source/entrypoint.rst:127
msgid "`AIOMISC_LOG_FLUSH` - interval between logs flushing from buffer"
msgstr "`AIOMISC_LOG_FLUSH` - интервал сброса буфера логов logs"

#: ../../source/entrypoint.rst:127
#: ../../source/entrypoint.rst:128
msgid "`AIOMISC_LOG_BUFFERING` - should logging be buffered"
msgstr "`AIOMISC_LOG_BUFFERING` - следует ли включать буфферизацию логирования"

#: ../../source/entrypoint.rst:128
#: ../../source/entrypoint.rst:129
msgid "`AIOMISC_LOG_BUFFER_SIZE` - maximum log buffer size"
msgstr "`AIOMISC_LOG_BUFFER_SIZE` - максимальный размер буфера логов"

#: ../../source/entrypoint.rst:129
#: ../../source/entrypoint.rst:130
msgid "`AIOMISC_POOL_SIZE` - thread pool size"
msgstr "`AIOMISC_POOL_SIZE` - размер пула потоков"

#: ../../source/entrypoint.rst:133
#: ../../source/entrypoint.rst:134
msgid "``run()`` shortcut"
msgstr "Функция ``run()``"

#: ../../source/entrypoint.rst:135
#: ../../source/entrypoint.rst:136
msgid ""
"``aiomisc.run()`` - it's the short way to create and destroy "
"``aiomisc.entrypoint``. It's very similar to ``asyncio.run()`` but handle"
Expand All @@ -243,7 +247,7 @@ msgstr ""
"управляет сервисами ``aiomisc.Service`` и принимает прочие аргументы "
"entrypoint."

#: ../../source/entrypoint.rst:139
#: ../../source/entrypoint.rst:140
msgid ""
"import asyncio\n"
"import aiomisc\n"
Expand All @@ -258,70 +262,78 @@ msgid ""
"aiomisc.run(main())"
msgstr ""

#: ../../source/entrypoint.rst:155
#: ../../source/entrypoint.rst:156
msgid "Logging configuration"
msgstr "Конфигурация журналов"

#: ../../source/entrypoint.rst:157
#: ../../source/entrypoint.rst:158
msgid ""
"``entrypoint`` accepts a specific set of formats in which logs will be "
"written to stderr."
"``entrypoint`` accepts ``log_format`` argument with a specific set of "
"formats, in which logs will be written to stderr:"
msgstr ""
"``entrypoint`` принимает определенный набор форматов, в которых журналы "
"будут записываться в stderr."
"``entrypoint`` принимает аргумент ``log_format`` с определенным набором "
"форматов, в которых журналы будут записываться в stderr."

#: ../../source/entrypoint.rst:160
#: ../../source/entrypoint.rst:161
msgid "``stream`` - Python's default logging handler"
msgstr "``stream`` - стандартный python логгер"

#: ../../source/entrypoint.rst:161
#: ../../source/entrypoint.rst:162
msgid "``color`` - logging with `colorlog` module"
msgstr "``color`` - логирование через модуль ``colorlog``"

#: ../../source/entrypoint.rst:162
#: ../../source/entrypoint.rst:163
msgid "``json`` - json structure per each line"
msgstr "``json`` - json структура, одна на строчку"

#: ../../source/entrypoint.rst:163
#: ../../source/entrypoint.rst:164
msgid "``syslog`` - logging using stdlib `logging.handlers.SysLogHandler`"
msgstr "``syslog`` - ``logging.handlers.SysLogHandler`` из стандартной библиотеки"

#: ../../source/entrypoint.rst:164
#: ../../source/entrypoint.rst:165
msgid "``plain`` - just log messages, without date or level info"
msgstr ""
"``plain`` - просто сообщения, без даты или финормации об уровне "
"логирования"

#: ../../source/entrypoint.rst:165
#: ../../source/entrypoint.rst:166
msgid ""
"``journald`` - available only when `logging-journald` module has been "
"installed."
msgstr ""
"``journald`` - доступно только если ``logging-journald`` модуль "
"установлен."

#: ../../source/entrypoint.rst:167
#: ../../source/entrypoint.rst:168
#, fuzzy
msgid ""
"``rich``/``rich_tb` - available only when `rich` module has been "
"``rich``/``rich_tb`` - available only when `rich` module has been "
"installed. ``rich_tb`` it's the same as ``rich`` but with fully expanded "
"tracebacks."
msgstr ""
"``rich``/``rich_tb`` - доступно только если ``rich`` модуль установлен. "
"``rich_tb`` тоже самое что и ``rich`` только с подробными трейсбэками."

#: ../../source/entrypoint.rst:170
#: ../../source/entrypoint.rst:171
msgid ""
"Additionally, you can specify log level using ``log_level`` argument and "
"date format using ``log_date_format`` parameters."
msgstr "Также вы можете настроить уровень логгирования параметром "
"``log_level`` и формат дат в логах параметром ``log_date_format``"

#: ../../source/entrypoint.rst:174
msgid ""
"An ``entrypoint`` will call ``aiomisc.log.basic_config`` function "
"implicitly using passed ``log_level=`` and ``log_format=`` parameters. "
"Alternatively you can call ``aiomisc.log.basic_config`` function manually"
" passing it already created eventloop."
"implicitly using passed ``log_*`` parameters. Alternatively you can call "
"``aiomisc.log.basic_config`` function manually passing it already created"
" eventloop."
msgstr ""
"``entrypoint`` вызовет ``aiomisc.log.basic_config`` неявно используя "
"пеараметры ``log_level=`` и ``log_format=``. Как альтернатива, вы можете "
"``entrypoint`` вызовет ``aiomisc.log.basic_config`` "
"неявно используя пеараметры ``log_*=``. В качестве альтернативы, вы можете "
"вызвать ``aiomisc.log.basic_config`` вручную передав ей экземпляр "
"``eventloop``."

#: ../../source/entrypoint.rst:175
#: ../../source/entrypoint.rst:179
msgid ""
"However, you can configure logging earlier using "
"``aiomisc_log.basic_config``, but you will lose log buffering and "
Expand All @@ -335,7 +347,7 @@ msgstr ""
"настройки ведения журнала, ``entrypoint`` передает обертку для logging "
"handler, чтобы он записывал в буфер в отдельном потоке."

#: ../../source/entrypoint.rst:181
#: ../../source/entrypoint.rst:185
msgid ""
"import logging\n"
"\n"
Expand All @@ -346,7 +358,7 @@ msgid ""
"logging.info(\"Hello\")"
msgstr ""

#: ../../source/entrypoint.rst:191
#: ../../source/entrypoint.rst:195
msgid ""
"If you want to configure logging before the ``entrypoint`` is started, "
"for example after the arguments parsing, it is safe to configure it twice"
Expand All @@ -356,7 +368,7 @@ msgstr ""
"например, после разбора аргументов, это безопасно настроить его дважды "
"(или больше)."

#: ../../source/entrypoint.rst:195
#: ../../source/entrypoint.rst:199
msgid ""
"import logging\n"
"\n"
Expand All @@ -376,15 +388,15 @@ msgid ""
" loop.run_until_complete(main())"
msgstr ""

#: ../../source/entrypoint.rst:215
#: ../../source/entrypoint.rst:219
msgid ""
"Sometimes you want to configure logging manually, the following example "
"demonstrates how to do this:"
msgstr ""
"Иногда вы хотите настроить ведение журнала самостоятельно, пример ниже "
"демонстрирует, как это сделать:"

#: ../../source/entrypoint.rst:218
#: ../../source/entrypoint.rst:222
#, python-format
msgid ""
"import os\n"
Expand Down
40 changes: 39 additions & 1 deletion tests/test_entrypoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,21 @@
from contextlib import ExitStack, suppress
from tempfile import mktemp
from typing import Any, Optional, Set, Tuple
from unittest import mock

import aiohttp.web
import fastapi
import pytest

import aiomisc
from aiomisc.entrypoint import Entrypoint
from aiomisc.entrypoint import Entrypoint, entrypoint
from aiomisc.service import TCPServer, TLSServer, UDPServer
from aiomisc.service.aiohttp import AIOHTTPService
from aiomisc.service.asgi import ASGIApplicationType, ASGIHTTPService
from aiomisc.service.tcp import RobustTCPClient, TCPClient
from aiomisc.service.tls import RobustTLSClient, TLSClient
from aiomisc_log import LogFormat
from aiomisc_log.enum import DateFormat, LogLevel
from tests import unix_only


Expand Down Expand Up @@ -884,3 +887,38 @@ async def test_add_remove_service(entrypoint: aiomisc.Entrypoint):
await entrypoint.start_services(service)

assert len(StorageService.INSTANCES) == 10


@pytest.mark.parametrize('entrypoint_logging_kwargs,basic_config_kwargs', [
(
{},
{
'level': LogLevel.info.name,
'log_format': LogFormat.plain.name,
'date_format': None
}
),
(
{
'log_level': LogLevel.debug,
'log_format': LogFormat.stream,
'log_date_format': DateFormat.stream
},
{
'level': LogLevel.debug,
'log_format': LogFormat.stream,
'date_format': DateFormat.stream
}
)
])
def test_entrypoint_log_params(entrypoint_logging_kwargs, basic_config_kwargs):
with mock.patch("aiomisc_log.basic_config") as basic_config_mock:
with entrypoint(**entrypoint_logging_kwargs):
pass

# unbuffered logging is configured on init, buffered on start,
# unbuffered on stop.
assert basic_config_mock.call_count == 3
for call_args, call_kwargs in basic_config_mock.call_args_list:
for key, value in basic_config_kwargs.items():
assert call_kwargs[key] == value

0 comments on commit fb38c68

Please sign in to comment.