Skip to content

Commit

Permalink
RSDK-5985 - per-resource logging (#769)
Browse files Browse the repository at this point in the history
  • Loading branch information
stuqdog authored Oct 30, 2024
1 parent ec7d994 commit c7b3d88
Show file tree
Hide file tree
Showing 6 changed files with 24 additions and 6 deletions.
3 changes: 0 additions & 3 deletions src/viam/components/board/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from grpclib.client import Channel
from grpclib.client import Stream as ClientStream

from viam.logging import getLogger
from viam.proto.common import DoCommandRequest, DoCommandResponse, Geometry
from viam.proto.component.board import (
BoardServiceStub,
Expand Down Expand Up @@ -33,8 +32,6 @@

from .board import Board, TickStream

LOGGER = getLogger(__name__)


class AnalogClient(Board.Analog):
def __init__(self, name: str, board: "BoardClient"):
Expand Down
5 changes: 4 additions & 1 deletion src/viam/components/component_base.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import abc
from logging import Logger
from typing import TYPE_CHECKING, Any, ClassVar, Dict, List, Mapping, Optional, SupportsBytes, SupportsFloat, Union, cast

from typing_extensions import Self

from viam.errors import MethodNotImplementedError
from viam.logging import getLogger
from viam.proto.common import Geometry
from viam.resource.base import ResourceBase

Expand All @@ -23,8 +25,9 @@ class ComponentBase(abc.ABC, ResourceBase):

SUBTYPE: ClassVar["Subtype"]

def __init__(self, name: str):
def __init__(self, name: str, *, logger: Optional[Logger] = None):
self.name = name
self.logger = logger if logger is not None else getLogger(f'{self.SUBTYPE}.{name}')

@classmethod
def from_robot(cls, robot: "RobotClient", name: str) -> Self:
Expand Down
11 changes: 10 additions & 1 deletion src/viam/logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ async def handle_task_result(self, task: asyncio.Task):

def emit(self, record: logging.LogRecord):
assert isinstance(record, logging.LogRecord)
name = record.name.split(".")[-1]
# Fully qualified name of form "{subtype triplet}/{name}", e.g. "rdk:component:arm/myarm"
name = record.name.replace('.', '/')
message = f"{record.filename}:{record.lineno}\t{record.getMessage()}"
stack = f"exc_info: {record.exc_info}, exc_text: {record.exc_text}, stack_info: {record.stack_info}"
time = datetime.fromtimestamp(record.created)
Expand Down Expand Up @@ -151,6 +152,14 @@ def addHandlers(logger: logging.Logger, use_default_handlers=False):
_addHandlers([logger], use_default_handlers)


def update_log_level(logger: logging.Logger, level: Union[int, str]):
if level == '':
level = LOG_LEVEL
logger.setLevel(level)
for handler in logger.handlers:
handler.setLevel(level)


def _addHandlers(loggers: Iterable[logging.Logger], use_default_handlers=False):
format = _ColorFormatter("%(asctime)s\t\t" + "%(levelname)s\t" + "%(name)s (%(filename)s:%(lineno)d)\t" + "%(message)s\t")

Expand Down
2 changes: 2 additions & 0 deletions src/viam/module/module.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

from viam import logging
from viam.errors import ResourceNotFoundError, ValidationError
from viam.logging import update_log_level
from viam.proto.app.robot import ComponentConfig
from viam.proto.module import (
AddResourceRequest,
Expand Down Expand Up @@ -183,6 +184,7 @@ async def add_resource(self, request: AddResourceRequest):
model = Model.from_string(config.model, ignore_errors=True)
creator = Registry.lookup_resource_creator(subtype, model)
resource = creator(config, dependencies)
update_log_level(resource.logger, config.log_configuration.level.upper())
self.server.register(resource)

async def reconfigure_resource(self, request: ReconfigureResourceRequest):
Expand Down
4 changes: 4 additions & 0 deletions src/viam/resource/base.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from abc import abstractmethod
from typing import TYPE_CHECKING, Any, ClassVar, Mapping, Optional, Protocol, runtime_checkable
from logging import Logger

from typing_extensions import Self

Expand All @@ -25,6 +26,9 @@ class ResourceBase(Protocol):
name: str
"""The name of the Resource"""

logger: Logger
"""A logger allowing for setting log levels on a per-resource basis"""

@classmethod
def get_resource_name(cls, name: str) -> ResourceName:
"""
Expand Down
5 changes: 4 additions & 1 deletion src/viam/services/service_base.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import abc
from logging import Logger
from typing import TYPE_CHECKING, ClassVar, Mapping, Optional, cast

from typing_extensions import Self

from viam.logging import getLogger
from viam.resource.base import ResourceBase
from viam.utils import ValueTypes

Expand All @@ -18,8 +20,9 @@ class ServiceBase(abc.ABC, ResourceBase):

SUBTYPE: ClassVar["Subtype"]

def __init__(self, name: str) -> None:
def __init__(self, name: str, *, logger: Optional[Logger] = None) -> None:
self.name = name
self.logger = logger if logger is not None else getLogger(f'{self.SUBTYPE}.{name}')

@classmethod
def from_robot(cls, robot: "RobotClient", name: str) -> Self:
Expand Down

0 comments on commit c7b3d88

Please sign in to comment.