From ab2a37259fe4a87bf19d0e5b2aa909203ea0b58d Mon Sep 17 00:00:00 2001 From: rmaddikery Date: Wed, 12 Aug 2026 16:54:17 +0200 Subject: [PATCH 1/5] Fix top-level documentation - Adds high-level overview of the mw::log decomposition - Remove outdated documentation - Restructure documentation to where it fits --- docs/components/datarouter/index.rst | 9 +- docs/components/mw/log/index.rst | 36 ------- docs/components/mw_log/architecture/index.rst | 6 ++ .../design_decisions/explicit_init.rst | 2 +- .../datarouter_backend/README.md | 1 + .../detailed_design/file_output_backend.md | 1 + .../mw_log/detailed_design/index.rst | 8 ++ docs/components/mw_log/index.rst | 53 ++++++++++ .../mw_log/mw_log_repository_boundary.puml | 51 ++++++++++ .../{mw/log => mw_log}/requirements.rst | 0 docs/features/logging/architecture/index.rst | 43 -------- docs/index.rst | 99 ++++++++----------- docs/logging/stats.rst | 8 +- score/mw/log/design/backend/BUILD | 41 ++++++++ .../backend/datarouter_backend/README.md | 18 ++-- .../log/design/backend/file_output_backend.md | 6 +- 16 files changed, 222 insertions(+), 160 deletions(-) delete mode 100644 docs/components/mw/log/index.rst create mode 100644 docs/components/mw_log/architecture/index.rst rename docs/{ => components/mw_log}/design_decisions/explicit_init.rst (97%) create mode 120000 docs/components/mw_log/detailed_design/datarouter_backend/README.md create mode 120000 docs/components/mw_log/detailed_design/file_output_backend.md create mode 100644 docs/components/mw_log/detailed_design/index.rst create mode 100644 docs/components/mw_log/index.rst create mode 100644 docs/components/mw_log/mw_log_repository_boundary.puml rename docs/components/{mw/log => mw_log}/requirements.rst (100%) delete mode 100644 docs/features/logging/architecture/index.rst create mode 100644 score/mw/log/design/backend/BUILD diff --git a/docs/components/datarouter/index.rst b/docs/components/datarouter/index.rst index 87afb0d0..63d538ff 100644 --- a/docs/components/datarouter/index.rst +++ b/docs/components/datarouter/index.rst @@ -13,12 +13,10 @@ # ******************************************************************************* -Data Router Documentation +Datarouter ========================= -This section is reserved for data router-specific documentation. - -.. comp:: Data Router +.. comp:: Datarouter :id: comp__data_router :security: YES :safety: ASIL_B @@ -26,7 +24,8 @@ This section is reserved for data router-specific documentation. :implements: logic_arc_int__logging__logging :belongs_to: feat__logging - This is the datarouter component responsible for routing log messages to remote Diagnostics Log and Trace (DLT) backend. + Datarouter is the DLT daemon executable. It reads records from source shared-memory ring buffers, manages source + sessions, routes messages to configured channels via UDP multicast, and reports source statistics and message drops. .. toctree:: :titlesonly: diff --git a/docs/components/mw/log/index.rst b/docs/components/mw/log/index.rst deleted file mode 100644 index 2742b25c..00000000 --- a/docs/components/mw/log/index.rst +++ /dev/null @@ -1,36 +0,0 @@ -.. - # ******************************************************************************* - # Copyright (c) 2026 Contributors to the Eclipse Foundation - # - # See the NOTICE file(s) distributed with this work for additional - # information regarding copyright ownership. - # - # This program and the accompanying materials are made available under the - # terms of the Apache License Version 2.0 which is available at - # https://www.apache.org/licenses/LICENSE-2.0 - # - # SPDX-License-Identifier: Apache-2.0 - # ******************************************************************************* - - -Logging Documentation -===================== - -This section is reserved for middleware-specific documentation. - -.. comp:: Logging Component - :id: comp__mw_logging - :security: YES - :safety: ASIL_B - :status: valid - :implements: logic_arc_int__logging__logging - :belongs_to: feat__logging - - This is the logging component library responsible for selecting the appropriate log sinks based on configuration at runtime. It can perform tasks such as log formatting, filtering, and composite backend selection based on runtime context and configuration. The logging component is designed to be extensible, allowing for custom logging backend to be added as needed. - -.. toctree:: - :titlesonly: - :maxdepth: 1 - :glob: - - * diff --git a/docs/components/mw_log/architecture/index.rst b/docs/components/mw_log/architecture/index.rst new file mode 100644 index 00000000..36bcaab5 --- /dev/null +++ b/docs/components/mw_log/architecture/index.rst @@ -0,0 +1,6 @@ +mw::log Architecture +============================ + +The backend composition and recorder relationships are shown below: + +.. uml:: ../../../../score/mw/log/design/backend/mw_log_recorders.puml diff --git a/docs/design_decisions/explicit_init.rst b/docs/components/mw_log/design_decisions/explicit_init.rst similarity index 97% rename from docs/design_decisions/explicit_init.rst rename to docs/components/mw_log/design_decisions/explicit_init.rst index b3128db3..4d38495d 100644 --- a/docs/design_decisions/explicit_init.rst +++ b/docs/components/mw_log/design_decisions/explicit_init.rst @@ -48,4 +48,4 @@ Explicit initialization of logging **Justification for the Decision** - Explicit logging initialization will simplify logging initialization in multi-language environments. + Explicit logging initialization will simplify logging initialization in multi-language environments. \ No newline at end of file diff --git a/docs/components/mw_log/detailed_design/datarouter_backend/README.md b/docs/components/mw_log/detailed_design/datarouter_backend/README.md new file mode 120000 index 00000000..d8f2edc1 --- /dev/null +++ b/docs/components/mw_log/detailed_design/datarouter_backend/README.md @@ -0,0 +1 @@ +../../../../../score/mw/log/design/backend/datarouter_backend/README.md \ No newline at end of file diff --git a/docs/components/mw_log/detailed_design/file_output_backend.md b/docs/components/mw_log/detailed_design/file_output_backend.md new file mode 120000 index 00000000..4e203407 --- /dev/null +++ b/docs/components/mw_log/detailed_design/file_output_backend.md @@ -0,0 +1 @@ +../../../../score/mw/log/design/backend/file_output_backend.md \ No newline at end of file diff --git a/docs/components/mw_log/detailed_design/index.rst b/docs/components/mw_log/detailed_design/index.rst new file mode 100644 index 00000000..76a546f4 --- /dev/null +++ b/docs/components/mw_log/detailed_design/index.rst @@ -0,0 +1,8 @@ +mw::log backend Detailed Design +=============================== + +.. toctree:: + :maxdepth: 1 + + file_output_backend + datarouter_backend/README diff --git a/docs/components/mw_log/index.rst b/docs/components/mw_log/index.rst new file mode 100644 index 00000000..37c9926e --- /dev/null +++ b/docs/components/mw_log/index.rst @@ -0,0 +1,53 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + + +mw::log +===================== + +.. comp:: Logging Component + :id: comp__mw_logging + :security: YES + :safety: ASIL_B + :status: valid + :implements: logic_arc_int__logging__logging + :belongs_to: feat__logging + + This is the logging middleware library responsible for providing conrete backends for the supported recorder + implementations. The logging component is designed to be extensible, allowing supported as well as custom logging + backend to be added as needed. + + The ``mw::log`` implementation spans two repositories: + + ``score_baselibs/score/mw/log`` provides the frontend API, console backend, and static recorder composition. + + ``score_logging/score/mw/log`` provides concrete file, remote/DLT, and slog recorders together with their backend + integration artifacts. + + Both repositories own their own safety plan, phase gates, and governance. The + cross-repository contract is the Recorder interface and static ``backend_table`` + registration. The existing C ABI seam is not used for static composition. + Runtime plugin loading remains experimental and is not a supported + production capability. + + .. uml:: mw_log_repository_boundary.puml + +.. toctree:: + :titlesonly: + :maxdepth: 1 + + requirements + architecture/index + detailed_design/index + design_decisions/explicit_init diff --git a/docs/components/mw_log/mw_log_repository_boundary.puml b/docs/components/mw_log/mw_log_repository_boundary.puml new file mode 100644 index 00000000..9565ace9 --- /dev/null +++ b/docs/components/mw_log/mw_log_repository_boundary.puml @@ -0,0 +1,51 @@ +@startuml mw_log_architecture +title mw::log (ASIL B): repository boundary + +skinparam componentStyle rectangle +skinparam packageStyle rectangle + +package "score_baselibs" as Baselibs #LightYellow { + component "mw::log Frontend API\n(logger, log_stream, runtime)" as Frontend + component "Console Backend\n(static, built-in)" as Console + component "Frontend safety plan\n+ AoU forwarding (Usage Contract)" as FrontendPlan + + Frontend -down-> Console : static composition (baseline) + Frontend .. FrontendPlan +} + +package "score_logging" as Logging #LightBlue { + component "mw::log Concrete Recorders\n(file, remote/DLT, slog)" as Recorders + component "Backend Integration\nArtifacts (datarouter_backend, ...)" as Integration + component "Backend safety plan\n+ AoU forwarding (Integration Contract)" as BackendPlan + + Recorders -down-> Integration : static registration + Recorders .. BackendPlan +} + +Recorders .up.> Frontend : implements Recorder interface\n(static registration via backend_table, baseline) + +package "Optional Future Evolution" as Future #WhiteSmoke { + component "Runtime Plugin Loading\n(dlopen-based)" as Runtime +} + +Runtime .[#gray]right.> Frontend : experimental only + +note bottom of Future + Not an assumed production + commitment; decision-gated. +end note + +note as N1 + Each repo owns its own phase gates, + safety plan, and governance; the only + cross-repo contract is the Recorder + interface + static backend_table + registration (plugin_api.h is an + existing C ABI seam, not used + for static composition). +end note + +Baselibs -[hidden]down-> N1 +Logging -[hidden]down-> N1 + +@enduml diff --git a/docs/components/mw/log/requirements.rst b/docs/components/mw_log/requirements.rst similarity index 100% rename from docs/components/mw/log/requirements.rst rename to docs/components/mw_log/requirements.rst diff --git a/docs/features/logging/architecture/index.rst b/docs/features/logging/architecture/index.rst deleted file mode 100644 index 8d0d1407..00000000 --- a/docs/features/logging/architecture/index.rst +++ /dev/null @@ -1,43 +0,0 @@ -Logging Module View -################### - - -.. mod:: Logging - :id: mod__logging_repo - :status: valid - :safety: ASIL_B - :security: YES - :includes: comp__data_router, comp__mw_logging - - The logging module provides a standardized logging framework for C++ and Rust projects using Bazel build system. It includes components for log routing allowing for flexible log management and integration with various logging backends. The module is designed to be extensible and configurable to meet the needs of different applications and environments. - -.. mod_view_sta:: Logging module view - :id: mod_view_sta__logging__logging_view - :includes: comp__data_router, comp__mw_logging - :belongs_to: mod__logging - - .. needarch:: - :scale: 50 - :align: center - - {{ draw_module(need(), needs) }} - - - -Logging Feature Architecture -############################ - -.. feat_arc_sta:: Feature Architecture Logging - :id: feat_arc_sta__logging__static_view - :security: YES - :safety: ASIL_B - :status: valid - :includes: logic_arc_int__logging__logging - :fulfils: feat_req__logging__log_sources_user_app - :belongs_to: feat__logging - - .. needarch:: - :scale: 50 - :align: center - - {{ draw_component(need(), needs) }} diff --git a/docs/index.rst b/docs/index.rst index 486953ef..6b58d565 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -12,10 +12,10 @@ # SPDX-License-Identifier: Apache-2.0 # ******************************************************************************* -Logging Documentation +Logging ===================== -This documentation describes the structure, usage and configuration of the Bazel-based C++/Rust logging module. +This module provides components for safety-critical logging (incl. DLT) in embedded automotive systems. .. contents:: Table of Contents :depth: 2 @@ -24,33 +24,41 @@ This documentation describes the structure, usage and configuration of the Bazel Overview -------- -This repository provides a standardized setup for projects using **C++** or **Rust** and **Bazel** as a build system. -It integrates best practices for build, test, CI/CD and documentation. +``score_logging`` delivers three distinct logging components: -Requirements ------------- +- ``mw::log`` is the logging middleware library. + Applications use the frontend API owned by `score_baselibs `_, + while `score_logging `_ provides the concrete + file, remote/DLT, and system recorder backend implementations. +- ``datarouter`` is the DLT daemon executable. + It reads records from source shared-memory ring buffers, manages source + sessions, routes messages to configured channels via UDP multicast, and reports source statistics and message drops. +- ``score_log_bridge`` is a Rust library that implements the ``score_log`` facade + using the C++ ``mw::log`` recorder + through a layout-checked FFI adapter. -.. stkh_req:: Example Functional Requirement - :id: stkh_req__docgen_enabled__example - :status: valid - :safety: QM - :security: YES - :reqtype: Functional - :valid_from: v1.0.0 - :rationale: Ensure documentation builds are possible for all modules - - -Project Layout --------------- +Repository Layout +----------------- The logging module includes the following top-level structure: -- ``score/``: Main C++/Rust sources -- ``tests/``: Unit and integration tests -- ``examples/``: Usage examples +- ``score/mw/log/``: ``mw::log`` recorders and concrete backends and Rust bridge +- ``score/datarouter/``: DLT daemon and supporting libraries +- ``test/``: Component and Integration tests - ``docs/``: Documentation using ``docs-as-code`` - ``.github/workflows/``: CI/CD pipelines +Components +---------- + +.. toctree:: + :titlesonly: + :maxdepth: 1 + :glob: + + components/mw_log/index.rst + components/datarouter/index.rst + Quick Start ----------- @@ -60,54 +68,31 @@ To build the module: bazel build //score/... -To run tests: +To run the supported test suites: .. code-block:: bash - bazel test //tests/... - -Configuration -------------- - -The ``project_config.bzl`` file defines metadata used by Bazel macros. - -Example: + # Unit tests on the Linux host + bazel test --config=x86_64-linux --test_tag_filters=unit //score/... -.. code-block:: python + # Component tests in Docker + bazel test --config=x86_64-linux --test_tag_filters=integration //score/test/component/... - PROJECT_CONFIG = { - "asil_level": "QM", - "source_code": ["cpp", "rust"] - } + # Integration tests on QNX/QEMU + bazel test --config=x86_64-qnx --test_tag_filters=integration //score/test/integration/... -This enables conditional behavior (e.g., choosing ``clang-tidy`` for C++ or ``clippy`` for Rust). - -Additional documentation ------------------------- +Configuration +------------- -.. toctree:: - :maxdepth: 1 +See the `mw::log configuration documentation`_. - features/logging/architecture/index - design_decisions/explicit_init +.. _mw::log configuration documentation: https://github.com/eclipse-score/baselibs/blob/main/score/mw/log/README.md#configuration -Components -========== +Stats +----- .. toctree:: :titlesonly: :maxdepth: 1 - :glob: - - components/datarouter/index.rst - components/mw/log/index.rst - - -Requirements ------------- - -.. toctree:: - :maxdepth: 1 - :glob: logging/stats.rst diff --git a/docs/logging/stats.rst b/docs/logging/stats.rst index badfdfb4..42563dfc 100644 --- a/docs/logging/stats.rst +++ b/docs/logging/stats.rst @@ -1,7 +1,7 @@ .. _log_statistics: -Component Requirements Statistics -================================= +Quality Stats +============== Overview -------- @@ -86,7 +86,9 @@ Details About Testcases ------------------------ .. needpie:: Test Types Used In Testcases - :labels: static-code-analysis, structural-statement-coverage, structural-branch-coverage, walkthrough, inspection, interface-test, requirements-based, resource-usage, control-flow-analysis, data-flow-analysis, fault-injection, struct-func-cov, struct-call-cov + :labels: static-code-analysis, structural-statement-coverage, structural-branch-coverage, walkthrough, inspection, + interface-test, requirements-based, resource-usage, control-flow-analysis, data-flow-analysis, fault-injection, + struct-func-cov, struct-call-cov :legend: type == 'testcase' and test_type == 'static-code-analysis' diff --git a/score/mw/log/design/backend/BUILD b/score/mw/log/design/backend/BUILD new file mode 100644 index 00000000..b420f289 --- /dev/null +++ b/score/mw/log/design/backend/BUILD @@ -0,0 +1,41 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + +load( + "@score_tooling//bazel/rules/rules_score:rules_score.bzl", + "architectural_design", +) + +architectural_design( + name = "mw_log_backend_architectural_design", + dynamic = [ + "datarouter_backend/datarouter_backend_datarouterbackend.puml", + "datarouter_backend/datarouter_message_client_impl_connecttodatarouter.puml", + "datarouter_backend/shared_memory_reader_read.puml", + "datarouter_backend/shared_memory_writer_allocandwrite.puml", + "datarouter_backend/verbose_logging_sequence.puml", + ], + static = [ + "datarouter_backend/README.md", + "datarouter_backend/datarouter_class_diagram.puml", + "datarouter_backend/inter_process_communication.puml", + "datarouter_backend/mw_log_datarouter_recorder.puml", + "datarouter_backend/mw_log_shared_memory_reader.puml", + "datarouter_backend/verbose_logging_static.puml", + "datarouter_backend/write_factory_design.puml", + "file_output_backend.md", + "mw_log_file_backend.puml", + "mw_log_recorders.puml", + ], + visibility = ["//visibility:public"], +) diff --git a/score/mw/log/design/backend/datarouter_backend/README.md b/score/mw/log/design/backend/datarouter_backend/README.md index 1a402d16..42139c3a 100644 --- a/score/mw/log/design/backend/datarouter_backend/README.md +++ b/score/mw/log/design/backend/datarouter_backend/README.md @@ -43,14 +43,13 @@ are as follows: In the Datarouter backend the goal is to safely and efficiently transfer the log messages from the user process to the Datarouter process. -The inter-process communication takes place via shared memory and the [message -passing library](../../../com/message_passing/design/README.md). This library -only supports unidirectional message transport. As we need bidirectional +The inter-process communication takes place via shared memory and the message +passing library. This library only supports unidirectional message transport. As we need bidirectional communication over the side channel, we establish two independent unidirectional channels. On the highest level of abstraction we see the ASIL-B qualified client process on the one side and the datarouter process on the other -![Inter-process communication](./score/mw/log/design/backend/datarouter_backend/inter_process_communication.puml). +INTER_PROCESS_COMMUNICATION. The logs are written by the client into shared memory and read-out by datarouter. Freedom of interference is ensured since the datarouter process has @@ -61,7 +60,7 @@ safety-qualified message passing library. ## Class diagram -![Class diagram](./score/mw/log/design/backend/datarouter_backend/datarouter_class_diagram.puml) +DATAROUTER_CLASS_DIAGRAM The class diagram above shows the relevant classes client-side and in Datarouter. Client-side the `DatarouterBackend` contains a circular allocator @@ -82,14 +81,13 @@ access to the ring buffer between Datarouter and the client. ## Activity diagrams -![DataRouterBackend::DataRouterBackend Activity diagram](./score/mw/log/design/backend/datarouter_backend/datarouter_backend_datarouterbackend.puml) +DATAROUTER_BACKEND_DATAROUTERBACKEND ## Lock-free Shared Memory Design The log messages from apps are transferred to Datarouter through shared memory. For lock- and wait-free data exchange we use the `WaitFreeAlternatingWriter` as -documented [here](../../detail/wait_free_producer_queue/README.md) as part of -the `SharedMemoryWriter` class. The data in shared memory is layed out in +part of the `SharedMemoryWriter` class. The data in shared memory is layed out in consecutive and contiguous segments: 1. Control structure `mw::log::detail::SharedData` at offset = 0. @@ -201,7 +199,7 @@ readable without synchronization. Only after reading the remaining data from the ring buffer, should Datarouter unmap the shared memory page. Then the OS should free up the used resources. -![SharedMemoryReader Class diagram](./score/mw/log/design/backend/datarouter_backend/mw_log_shared_memory_reader.puml) +MW_LOG_SHARED_MEMORY_READER ## Limited impact of incoming messages in the logging client @@ -227,7 +225,7 @@ after each incoming request. The side channel in logging is needed to synchronize the access to the data in shared memory between the client and Datarouter. Previously, the channel was implemented using unix domain sockets. Here, we replace unix domain sockets by -[message passing](../../../com/message_passing/design/README.md). +message passing. Datarouter periodically scans for new clients and initiates the message exchange. In the message exchange between Datarouter and the Clients, diff --git a/score/mw/log/design/backend/file_output_backend.md b/score/mw/log/design/backend/file_output_backend.md index 34999898..eae14a3d 100644 --- a/score/mw/log/design/backend/file_output_backend.md +++ b/score/mw/log/design/backend/file_output_backend.md @@ -31,17 +31,13 @@ or onto the console. `MessageBuilder` is responsible for serving data in correct order of flushing into file or console and stores some of common parts of the header. -![Static Design](./score/mw/log/design/backend/mw_log_file_backend.puml) +MW_LOG_FILE_BACKEND `SlotDrainer` is responsible for storing and disposal of already serialized data. First data gets inserted into circular buffer. After that step program flow enters a loop that iterates over available slots in ring buffer and then by means of `NonBlockingWriter` iterates over all spans of each message. -![Sequence Design](./score/mw/log/design/slot_drainer_sequence_design.puml) - Flush procedure exits whenever all available data is written to the file or writing procedure would block i.e. write operation reports that number of bytes written is less then requested. - -![Action Diagram](./score/mw/log/design/slot_drainer_action_diagram_design.puml) From 04373c099cb880032b2ea2d7d480d9a3ad1f0207 Mon Sep 17 00:00:00 2001 From: rmaddikery Date: Wed, 12 Aug 2026 19:31:49 +0200 Subject: [PATCH 2/5] Adds a section for the rust log bridge --- .../mw_log/mw_log_repository_boundary.puml | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/docs/components/mw_log/mw_log_repository_boundary.puml b/docs/components/mw_log/mw_log_repository_boundary.puml index 9565ace9..4e8dca59 100644 --- a/docs/components/mw_log/mw_log_repository_boundary.puml +++ b/docs/components/mw_log/mw_log_repository_boundary.puml @@ -3,11 +3,13 @@ title mw::log (ASIL B): repository boundary skinparam componentStyle rectangle skinparam packageStyle rectangle +skinparam linetype ortho package "score_baselibs" as Baselibs #LightYellow { component "mw::log Frontend API\n(logger, log_stream, runtime)" as Frontend component "Console Backend\n(static, built-in)" as Console - component "Frontend safety plan\n+ AoU forwarding (Usage Contract)" as FrontendPlan + component "score_log Rust Facade\n(score_log, score_log_fmt,\nscore_log_fmt_macro)" as RustFacade + artifact "Frontend safety plan\n+ AoU forwarding (Usage Contract)" as FrontendPlan #line.dashed Frontend -down-> Console : static composition (baseline) Frontend .. FrontendPlan @@ -15,8 +17,10 @@ package "score_baselibs" as Baselibs #LightYellow { package "score_logging" as Logging #LightBlue { component "mw::log Concrete Recorders\n(file, remote/DLT, slog)" as Recorders - component "Backend Integration\nArtifacts (datarouter_backend, ...)" as Integration - component "Backend safety plan\n+ AoU forwarding (Integration Contract)" as BackendPlan + component "Backend Integration\ntargets (file, remote/datarouter, ...)" as Integration + component "Rust Log Bridge\n(score_log_bridge + adapter.cpp)" as RustBridge + component "Rust Bridge C++ Init API\n(score_log_bridge_cpp_init)" as RustCppInit + artifact "Backend safety plan\n+ AoU forwarding (Integration Contract)" as BackendPlan #line.dashed Recorders -down-> Integration : static registration Recorders .. BackendPlan @@ -24,6 +28,11 @@ package "score_logging" as Logging #LightBlue { Recorders .up.> Frontend : implements Recorder interface\n(static registration via backend_table, baseline) +RustBridge -up-> RustFacade : implements score_log\nlogger backend +RustBridge -right-> Frontend : adapter.cpp calls\nRuntime::GetRecorder() (FFI) +RustBridge .up.> Recorders : direct static link\n(score/issues/2848) +RustCppInit -down-> RustBridge : set_default_logger (FFI)\nconfigures default logger + package "Optional Future Evolution" as Future #WhiteSmoke { component "Runtime Plugin Loading\n(dlopen-based)" as Runtime } @@ -42,7 +51,10 @@ note as N1 interface + static backend_table registration (plugin_api.h is an existing C ABI seam, not used - for static composition). + for static composition). The Rust + bridge reaches the Frontend/Recorders + the same way, via direct static + linkage rather than backend_table. end note Baselibs -[hidden]down-> N1 From a5f3bf5dc212a8e632471640c8d7e0f17b0b26f7 Mon Sep 17 00:00:00 2001 From: rmaddikery Date: Wed, 12 Aug 2026 20:54:34 +0200 Subject: [PATCH 3/5] Links datarouter documentation to top-level docs - Fixes .puml rendering --- .../detailed_design/logging_architecture.md | 1 + .../datarouter/detailed_design/shm_apis.md | 1 + docs/components/datarouter/index.rst | 11 +++++- docs/guides/configuration.md | 1 + docs/guides/dlt_capture_demo.md | 1 + docs/guides/etc/log-channels.json | 1 + docs/guides/etc/logging.json | 1 + docs/guides/file_based_local.md | 1 + docs/guides/index.rst | 14 +++++++ docs/index.rst | 25 +++++++----- .../doc/design/logging_architecture.md | 39 +++++++++---------- .../datarouter/doc/guideline/configuration.md | 4 +- .../doc/guideline/file_based_local.md | 2 +- .../backend/datarouter_backend/README.md | 9 ++--- .../log/design/backend/file_output_backend.md | 4 ++ 15 files changed, 75 insertions(+), 40 deletions(-) create mode 120000 docs/components/datarouter/detailed_design/logging_architecture.md create mode 120000 docs/components/datarouter/detailed_design/shm_apis.md create mode 120000 docs/guides/configuration.md create mode 120000 docs/guides/dlt_capture_demo.md create mode 120000 docs/guides/etc/log-channels.json create mode 120000 docs/guides/etc/logging.json create mode 120000 docs/guides/file_based_local.md create mode 100644 docs/guides/index.rst diff --git a/docs/components/datarouter/detailed_design/logging_architecture.md b/docs/components/datarouter/detailed_design/logging_architecture.md new file mode 120000 index 00000000..3fce7883 --- /dev/null +++ b/docs/components/datarouter/detailed_design/logging_architecture.md @@ -0,0 +1 @@ +../../../../score/datarouter/doc/design/logging_architecture.md \ No newline at end of file diff --git a/docs/components/datarouter/detailed_design/shm_apis.md b/docs/components/datarouter/detailed_design/shm_apis.md new file mode 120000 index 00000000..97ce8f5f --- /dev/null +++ b/docs/components/datarouter/detailed_design/shm_apis.md @@ -0,0 +1 @@ +../../../../score/datarouter/doc/design/shm_apis.md \ No newline at end of file diff --git a/docs/components/datarouter/index.rst b/docs/components/datarouter/index.rst index 63d538ff..69bb11b6 100644 --- a/docs/components/datarouter/index.rst +++ b/docs/components/datarouter/index.rst @@ -19,14 +19,21 @@ Datarouter .. comp:: Datarouter :id: comp__data_router :security: YES - :safety: ASIL_B + :safety: QM :status: valid :implements: logic_arc_int__logging__logging :belongs_to: feat__logging - Datarouter is the DLT daemon executable. It reads records from source shared-memory ring buffers, manages source + Datarouter is the DLT (Diagnostic log and trace) daemon executable. It reads records from source shared-memory ring buffers, manages source sessions, routes messages to configured channels via UDP multicast, and reports source statistics and message drops. +.. toctree:: + :titlesonly: + :maxdepth: 1 + + detailed_design/logging_architecture + detailed_design/shm_apis + .. toctree:: :titlesonly: :maxdepth: 1 diff --git a/docs/guides/configuration.md b/docs/guides/configuration.md new file mode 120000 index 00000000..f58bd44a --- /dev/null +++ b/docs/guides/configuration.md @@ -0,0 +1 @@ +../../score/datarouter/doc/guideline/configuration.md \ No newline at end of file diff --git a/docs/guides/dlt_capture_demo.md b/docs/guides/dlt_capture_demo.md new file mode 120000 index 00000000..dfaa073c --- /dev/null +++ b/docs/guides/dlt_capture_demo.md @@ -0,0 +1 @@ +../../score/datarouter/doc/guideline/dlt_capture_demo.md \ No newline at end of file diff --git a/docs/guides/etc/log-channels.json b/docs/guides/etc/log-channels.json new file mode 120000 index 00000000..f4c574d9 --- /dev/null +++ b/docs/guides/etc/log-channels.json @@ -0,0 +1 @@ +../../../score/datarouter/doc/guideline/etc/log-channels.json \ No newline at end of file diff --git a/docs/guides/etc/logging.json b/docs/guides/etc/logging.json new file mode 120000 index 00000000..4a712e68 --- /dev/null +++ b/docs/guides/etc/logging.json @@ -0,0 +1 @@ +../../../score/datarouter/doc/guideline/etc/logging.json \ No newline at end of file diff --git a/docs/guides/file_based_local.md b/docs/guides/file_based_local.md new file mode 120000 index 00000000..fd403042 --- /dev/null +++ b/docs/guides/file_based_local.md @@ -0,0 +1 @@ +../../score/datarouter/doc/guideline/file_based_local.md \ No newline at end of file diff --git a/docs/guides/index.rst b/docs/guides/index.rst new file mode 100644 index 00000000..f27282e4 --- /dev/null +++ b/docs/guides/index.rst @@ -0,0 +1,14 @@ +Userguide +----------- + +Start with the `mw::log Usage Guide `_ to learn how to instrument your application with the logging API. + +The guides below then walk through configuration and typical logging setups, from basic to advanced: + +.. toctree:: + :titlesonly: + :maxdepth: 1 + + configuration + file_based_local + dlt_capture_demo diff --git a/docs/index.rst b/docs/index.rst index 6b58d565..e5d2353e 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -42,10 +42,15 @@ Repository Layout The logging module includes the following top-level structure: +- ``docs/``: Documentation using ``docs-as-code`` +- ``examples/``: Dash-tool license-check +- ``quality/``: integration-test (QEMU) environment configs and sanitizer suppression files (ASan/LSan/TSan/UBSan). - ``score/mw/log/``: ``mw::log`` recorders and concrete backends and Rust bridge - ``score/datarouter/``: DLT daemon and supporting libraries -- ``test/``: Component and Integration tests -- ``docs/``: Documentation using ``docs-as-code`` +- ``score/test/``: Component and Integration tests +- ``scripts/``: developer-tooling helpers +- ``third_party/``: bazel wiring for external tooling deps +- ``tools/``: developer-tooling - ``.github/workflows/``: CI/CD pipelines Components @@ -81,13 +86,6 @@ To run the supported test suites: # Integration tests on QNX/QEMU bazel test --config=x86_64-qnx --test_tag_filters=integration //score/test/integration/... -Configuration -------------- - -See the `mw::log configuration documentation`_. - -.. _mw::log configuration documentation: https://github.com/eclipse-score/baselibs/blob/main/score/mw/log/README.md#configuration - Stats ----- @@ -96,3 +94,12 @@ Stats :maxdepth: 1 logging/stats.rst + +Guides +--------- + +.. toctree:: + :titlesonly: + :maxdepth: 1 + + guides/index diff --git a/score/datarouter/doc/design/logging_architecture.md b/score/datarouter/doc/design/logging_architecture.md index cc4b882b..d2209b5d 100644 --- a/score/datarouter/doc/design/logging_architecture.md +++ b/score/datarouter/doc/design/logging_architecture.md @@ -50,9 +50,9 @@ The following constraints influenced the logging infrastructure design: ## Context The diagram below illustrates the logging framework context: -[context-ecu](uml/context-ecu.puml) +CONTEXT_ECU -Applications write log data through logging interfaces [^logging_vs_tracing]. +Applications write log data through logging interfaces. The logging framework transmits data to the following sinks: @@ -66,7 +66,7 @@ The logging framework transmits data to the following sinks: ### Process structure -[context-highlevel](uml/context-highlevel.puml) +CONTEXT_HIGHLEVEL The logging framework implements multiple components to meet system goals: @@ -105,7 +105,7 @@ The system defines the following visitors: 2. `TRACE(S)` is a C++ **function template** (not a preprocessor macro). Its call chain at runtime is: -```c++ +```text TRACE(arg) → LogEntry::Instance().TryWriteIntoSharedMemory(arg) → SharedMemoryWriter::AllocAndWrite(serialize_fn, type_id, size) @@ -117,7 +117,7 @@ On the first call for a given type `T`, `LogEntry::Instance()` (a Meyers sing The diagram below illustrates the high-level class structure of the datarouter component. -[package-datarouter](uml/package-datarouter.puml) +PACKAGE_DATAROUTER ## Runtime view @@ -127,12 +127,12 @@ Applications access logging functionality through `mw::log`. Initialization stage 1 executes when the first log request occurs. This may occur in global object constructors before the `main()` function executes, causing implicit initialization that creates necessary singletons automatically. The activity diagram below depicts the first-run process: -[seq-trace](uml/seq-trace.puml) +SEQ_TRACE ### mw::log implementation The `mw::log` implementation creates log records and commits them atomically to shared memory on flush. -[log-filtering-client-end](uml/dlt_message_filtering_frontend.puml) +DLT_MESSAGE_FILTERING_FRONTEND ### Ring buffer and linear allocator buffer @@ -143,15 +143,21 @@ Shared memory IPC provides optimal speed and flexibility for this implementation The Datarouter-Client Session uses [message_passing](https://github.com/eclipse-score/communication/tree/main/score/message_passing) IPC for the initial connection, buffer acquire requests, notifications, and disconnections. The `DataRouterRecorder` sets up the session when it is created and closes it when it is destroyed. In between, the datarouter keeps one `IServerConnection` handle per client and drives the log acquisition from the server side. -The main idea is to keep clients independent, so that one non-responsive client should not stall the datarouter. This matters because the datarouter serves all clients from a single thread, one after another on each periodic tick, so a single blocking call would hold up every other client. To avoid this, the datarouter asks for buffers (to read) using non-blocking QNX pulses (`IServerConnection::Notify()`), which return right away and never wait on the client. So if a client is slow or stuck, its pulse simply stays unanswered while the healthy clients keep getting served. See [session_sequence_diagram](uml/client_session_interaction_sequence.puml) for the full flow. +The main idea is to keep clients independent, so that one non-responsive client should not stall the datarouter. This matters because the datarouter serves all clients from a single thread, one after another on each periodic tick, so a single blocking call would hold up every other client. To avoid this, the datarouter asks for buffers (to read) using non-blocking QNX pulses (`IServerConnection::Notify()`), which return right away and never wait on the client. So if a client is slow or stuck, its pulse simply stays unanswered while the healthy clients keep getting served. See below for the full flow. + +CLIENT_SESSION_INTERACTION_SEQUENCE + +However, with such a design there are risks of stale sessions. A small per-session watchdog limits how long the datarouter waits for an acquire response. If a client keeps missing its deadline, the watchdog cleans up the stale session, but first it does a best-effort read of the client's last buffer so no logs are lost unnecessarily. See below. -However, with such a design there are risks of stale sessions. A small per-session watchdog limits how long the datarouter waits for an acquire response. If a client keeps missing its deadline, the watchdog cleans up the stale session, but first it does a best-effort read of the client's last buffer so no logs are lost unnecessarily. See [activity_watchdog_session](uml/activity_watchdog_session_lifecycle.puml). +ACTIVITY_WATCHDOG_SESSION_LIFECYCLE -The setup also handles an early-disconnect race, wherein if a client crashes while the datarouter is still building its session, the connect and disconnect paths work together to throw away the half-built session instead of keeping a dangling connection pointer. The client can then reconnect cleanly afterwards. See [early_disconnect_race](uml/sequence_early_disconnect_race.puml). +The setup also handles an early-disconnect race, wherein if a client crashes while the datarouter is still building its session, the connect and disconnect paths work together to throw away the half-built session instead of keeping a dangling connection pointer. The client can then reconnect cleanly afterwards. See below. + +SEQUENCE_EARLY_DISCONNECT_RACE ### datarouter -[log-filtering-datarouter](uml/dlt_message_filtering_backend.puml) +DLT_MESSAGE_FILTERING_BACKEND ### Application-side library configuration @@ -161,15 +167,6 @@ The system reads configuration from the `logging.json` file located in `/opt/ + Flush procedure exits whenever all available data is written to the file or writing procedure would block i.e. write operation reports that number of bytes written is less then requested. + +SlotDrainerActionDiagram From 9f04a796587ab1929ecfc2fd39044b17f2c5e36b Mon Sep 17 00:00:00 2001 From: rmaddikery Date: Thu, 13 Aug 2026 12:12:51 +0200 Subject: [PATCH 4/5] Fix top-level README.md - Replace duplicated content with redirection to single source that resides next to source code rendered by Sphinx --- README.md | 114 ++++++++++++++++----------------------------- docs/index.rst | 12 +++++ project_config.bzl | 5 +- 3 files changed, 54 insertions(+), 77 deletions(-) diff --git a/README.md b/README.md index 306317c0..86aa3070 100644 --- a/README.md +++ b/README.md @@ -1,32 +1,25 @@ -# C++ & Rust Bazel Template Repository +# Logging -This repository serves as a **template** for setting up **C++ and Rust projects** using **Bazel**. -It provides a **standardized project structure**, ensuring best practices for: +This module provides components (`mw::log`, `datarouter`, `score_log_bridge`) for +safety-critical logging (Diagnostic Log and Trace) in embedded automotive systems. -- **Build configuration** with Bazel. -- **Testing** (unit and integration tests). -- **Documentation** setup. -- **CI/CD workflows**. -- **Development environment** configuration. +See the [module documentation](docs/index.rst) for the full overview, repository layout, and component +architecture. --- -## 📂 Project Structure - -| File/Folder | Description | -| ----------------------------------- | ------------------------------------------------- | -| `README.md` | Short description & build instructions | -| `score/` | Source files for the module | -| `tests/` | Unit tests (UT) and integration tests (IT) | -| `examples/` | Example files used for guidance | -| `docs/` | Documentation (Doxygen for C++ / mdBook for Rust) | -| `.github/workflows/` | CI/CD pipelines | -| `.vscode/` | Recommended VS Code settings | -| `.bazelrc`, `MODULE.bazel`, `BUILD` | Bazel configuration & settings | -| `project_config.bzl` | Project-specific metadata for Bazel macros | -| `LICENSE.md` | Licensing information | -| `CONTRIBUTION.md` | Contribution guidelines | +## 📂 Key Files + +| File/Folder | Description | +| ------------------------------------ | -------------------------------------------------- | +| `README.md` | Short description & build instructions | +| `score/` | Source files and tests for the module | +| `docs/` | Documentation using `docs-as-code` | +| `.bazelrc`, `MODULE.bazel`, `BUILD` | Bazel configuration & settings | +| `project_config.bzl` | Project-specific metadata for Bazel macros | +| `LICENSE.md` | Licensing information | +| `CONTRIBUTION.md` | Contribution guidelines | --- @@ -35,84 +28,55 @@ It provides a **standardized project structure**, ensuring best practices for: ### 1️⃣ Clone the Repository ```sh -git clone https://github.com/eclipse-score/YOUR_PROJECT.git -cd YOUR_PROJECT +git clone https://github.com/eclipse-score/logging.git +cd logging ``` -### 2️⃣ Build the Examples of module - -> DISCLAIMER: Depending what module implements, it's possible that different -> configuration flags needs to be set on command line. - -To build all targets of the module the following command can be used: +### 2️⃣ Build & Run Tests -```sh -bazel build //score/... -``` +See the [Quick Start](docs/index.rst) section of the module documentation for the exact `bazel build`/ +`bazel test` commands (including the platform `--config` and `--test_tag_filters` needed to select +unit, component, or QNX/QEMU integration tests). -This command will instruct Bazel to build all targets that are under Bazel -package `score/`. The ideal solution is to provide single target that builds -artifacts, for example: +> TIP: For a single release-artifact target, provide a `:release_artifacts` filegroup per module +> (e.g. `bazel build //score/:release_artifacts`) — final decision is up to the module +> maintainer. -```sh -bazel build //score/:release_artifacts -``` - -where `:release_artifacts` is filegroup target that collects all release -artifacts of the module. +--- -> NOTE: This is just proposal, the final decision is on module maintainer how -> the module code needs to be built. +## 📖 Documentation -### 3️⃣ Run Tests +Documentation lives in `docs/` and is built with `docs-as-code` (Sphinx). Build it locally with: ```sh -bazel test //tests/... +bazel build //:docs ``` ---- - -## 🛠 Tools & Linters - -The template integrates **tools and linters** from **centralized repositories** to ensure consistency across projects. - -- **C++:** `clang-tidy`, `cppcheck`, `Google Test` -- **Rust:** `clippy`, `rustfmt`, `Rust Unit Tests` -- **CI/CD:** GitHub Actions for automated builds and tests +See the [module documentation](docs/index.rst) for the rendered content. --- -## 📖 Documentation +## ✅ Quality -- A **centralized docs structure** is planned. +See the [Quality](docs/index.rst) section of the module documentation for the existing tooling and the +KPIs each one gates in CI (static analysis/linters, sanitizers, coverage, test tiers, traceability, license compliance). --- ## ⚙️ `project_config.bzl` -This file defines project-specific metadata used by Bazel macros, such as `dash_license_checker`. - -### 📌 Purpose - -It provides structured configuration that helps determine behavior such as: - -- Source language type (used to determine license check file format) -- Safety level or other compliance info (e.g. ASIL level) - -### 📄 Example Content +Project-specific metadata consumed by the shared Dash license-check CI convention (`license_check.yml`), +`source_code` picks which dependency lockfile gets scanned (`cargo` for Rust); `asil_level` records +the module's safety level for compliance reporting. ```python PROJECT_CONFIG = { - "asil_level": "QM", # or "ASIL-A", "ASIL-B", etc. - "source_code": ["cpp", "rust"] # Languages used in the module + # Module is mixed-criticality (mw::log backends ASIL_B, datarouter QM); highest level is declared here. + "asil_level": "ASIL_B", + "source_code": ["cpp", "rust"], } ``` -### 🔧 Use Case - -When used with macros like `dash_license_checker`, it allows dynamic selection of file types - (e.g., `cargo`, `requirements`) based on the languages declared in `source_code`. - ## IDE support ### Rust diff --git a/docs/index.rst b/docs/index.rst index e5d2353e..5d3358ad 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -86,6 +86,18 @@ To run the supported test suites: # Integration tests on QNX/QEMU bazel test --config=x86_64-qnx --test_tag_filters=integration //score/test/integration/... +Quality +------- + +Existing tooling and the KPIs each one gates in CI (see ``.github/workflows/``): + +- **Static analysis** — ``clang-tidy`` on every C++ target; ``clippy``/``rustfmt`` (``rustfmt.toml``) for Rust. +- **Sanitizers** — ASan/UBSan/LSan/TSan runs per PR, suppressions are placed in ``quality/sanitizer/``. +- **Code coverage** — C++ line/branch coverage report, excluding integration-tagged tests. +- **Test suites** — Google Test/Rust unit tests (Linux), component (Docker), and integration (QNX/QEMU) tests run separately. +- **License compliance** — Dash license scan of C++/Rust dependencies. +- **Copyright & format** — header and formatting checks on every change. + Stats ----- diff --git a/project_config.bzl b/project_config.bzl index 67aee1f8..e920b198 100644 --- a/project_config.bzl +++ b/project_config.bzl @@ -12,6 +12,7 @@ # ******************************************************************************* # project_config.bzl PROJECT_CONFIG = { - "asil_level": "QM", - "source_code": ["rust"], + # Module is mixed-criticality (mw::log backends ASIL_B, datarouter QM); highest level is declared here. + "asil_level": "ASIL_B", + "source_code": ["cpp", "rust"], } From 2ddff51fea69fe044f947c5b59a14a0acbc3f4e9 Mon Sep 17 00:00:00 2001 From: rmaddikery Date: Fri, 14 Aug 2026 13:59:35 +0200 Subject: [PATCH 5/5] Fix review comments - Reflect score folder structure guideline - Adds high level architecture documentation and references related diagrams --- README.md | 35 ------ docs/components/datarouter/index.rst | 10 +- .../index.rst} | 12 +- docs/components/mw_log/architecture/index.rst | 6 - .../mw_log/detailed_design/index.rst | 4 + docs/components/mw_log/index.rst | 20 +--- .../index.rst} | 0 .../_assets}/mw_log_repository_boundary.puml | 0 .../architecture/_assets/remote_logging.puml | 107 ++++++++++++++++++ docs/features/architecture/index.rst | 67 +++++++++++ docs/guides/configuration.md | 1 - docs/guides/dlt_capture_demo.md | 1 - docs/guides/etc/log-channels.json | 1 - docs/guides/etc/logging.json | 1 - docs/guides/file_based_local.md | 1 - docs/guides/index.rst | 14 --- docs/index.rst | 13 ++- docs/module/manuals/config/configuration.md | 1 + .../manuals/config/etc/log-channels.json | 1 + docs/module/manuals/config/etc/logging.json | 1 + .../manuals/examples/dlt_capture_demo.md | 1 + .../manuals/examples/file_based_local.md | 1 + docs/module/manuals/index.rst | 28 +++++ .../stats.rst | 0 .../doc/design/remote_logging.plantuml | 94 ++++++++------- .../doc/design/uml/context-highlevel.puml | 33 +++--- 26 files changed, 304 insertions(+), 149 deletions(-) rename docs/components/datarouter/{requirements.rst => requirements/index.rst} (95%) delete mode 100644 docs/components/mw_log/architecture/index.rst rename docs/components/mw_log/{requirements.rst => requirements/index.rst} (100%) rename docs/{components/mw_log => features/architecture/_assets}/mw_log_repository_boundary.puml (100%) create mode 100644 docs/features/architecture/_assets/remote_logging.puml create mode 100644 docs/features/architecture/index.rst delete mode 120000 docs/guides/configuration.md delete mode 120000 docs/guides/dlt_capture_demo.md delete mode 120000 docs/guides/etc/log-channels.json delete mode 120000 docs/guides/etc/logging.json delete mode 120000 docs/guides/file_based_local.md delete mode 100644 docs/guides/index.rst create mode 120000 docs/module/manuals/config/configuration.md create mode 120000 docs/module/manuals/config/etc/log-channels.json create mode 120000 docs/module/manuals/config/etc/logging.json create mode 120000 docs/module/manuals/examples/dlt_capture_demo.md create mode 120000 docs/module/manuals/examples/file_based_local.md create mode 100644 docs/module/manuals/index.rst rename docs/{logging => verification_report}/stats.rst (100%) diff --git a/README.md b/README.md index 86aa3070..69117610 100644 --- a/README.md +++ b/README.md @@ -9,29 +9,8 @@ architecture. --- -## 📂 Key Files - -| File/Folder | Description | -| ------------------------------------ | -------------------------------------------------- | -| `README.md` | Short description & build instructions | -| `score/` | Source files and tests for the module | -| `docs/` | Documentation using `docs-as-code` | -| `.bazelrc`, `MODULE.bazel`, `BUILD` | Bazel configuration & settings | -| `project_config.bzl` | Project-specific metadata for Bazel macros | -| `LICENSE.md` | Licensing information | -| `CONTRIBUTION.md` | Contribution guidelines | - ---- - ## 🚀 Getting Started -### 1️⃣ Clone the Repository - -```sh -git clone https://github.com/eclipse-score/logging.git -cd logging -``` - ### 2️⃣ Build & Run Tests See the [Quick Start](docs/index.rst) section of the module documentation for the exact `bazel build`/ @@ -63,20 +42,6 @@ KPIs each one gates in CI (static analysis/linters, sanitizers, coverage, test t --- -## ⚙️ `project_config.bzl` - -Project-specific metadata consumed by the shared Dash license-check CI convention (`license_check.yml`), -`source_code` picks which dependency lockfile gets scanned (`cargo` for Rust); `asil_level` records -the module's safety level for compliance reporting. - -```python -PROJECT_CONFIG = { - # Module is mixed-criticality (mw::log backends ASIL_B, datarouter QM); highest level is declared here. - "asil_level": "ASIL_B", - "source_code": ["cpp", "rust"], -} -``` - ## IDE support ### Rust diff --git a/docs/components/datarouter/index.rst b/docs/components/datarouter/index.rst index 69bb11b6..592ae102 100644 --- a/docs/components/datarouter/index.rst +++ b/docs/components/datarouter/index.rst @@ -17,7 +17,7 @@ Datarouter ========================= .. comp:: Datarouter - :id: comp__data_router + :id: comp__datarouter :security: YES :safety: QM :status: valid @@ -31,12 +31,6 @@ Datarouter :titlesonly: :maxdepth: 1 + requirements/index detailed_design/logging_architecture detailed_design/shm_apis - -.. toctree:: - :titlesonly: - :maxdepth: 1 - :glob: - - * diff --git a/docs/components/datarouter/requirements.rst b/docs/components/datarouter/requirements/index.rst similarity index 95% rename from docs/components/datarouter/requirements.rst rename to docs/components/datarouter/requirements/index.rst index 2213d652..24fd3337 100644 --- a/docs/components/datarouter/requirements.rst +++ b/docs/components/datarouter/requirements/index.rst @@ -32,7 +32,7 @@ Datarouter Services :safety: QM :derived_from: feat_req__logging__compat_dlt, feat_req__logging__log_sinks_network :status: valid - :belongs_to: comp__data_router + :belongs_to: comp__datarouter Datarouter shall implement DLT server component. Datarouter provides the functionality to send messages using DLT protocol over UDP multicast transport. @@ -44,7 +44,7 @@ Datarouter Services :safety: QM :derived_from: feat_req__logging__compat_dlt, feat_req__logging__config_log_filter, feat_req__logging__config_entity_id :status: valid - :belongs_to: comp__data_router + :belongs_to: comp__datarouter DLT server shall support multiple log channels as specified in AUTOSAR Diagnostic, Log and Trace Protocol Specification. The following parameters shall be configurable statically via @@ -60,7 +60,7 @@ Datarouter Services :safety: QM :derived_from: feat_req__logging__filtering_log_levels, feat_req__logging__filtering_entity_id, feat_req__logging__config_log_filter :status: valid - :belongs_to: comp__data_router + :belongs_to: comp__datarouter DLT server shall support filtering of messages within each channel. The filter shall be parametrized with application ID, context ID, log level threshold. Initial filter set shall @@ -74,7 +74,7 @@ Datarouter Services :safety: QM :derived_from: feat_req__logging__compat_dlt :status: valid - :belongs_to: comp__data_router + :belongs_to: comp__datarouter DLT server shall provide support for verbose DLT messages. Messages sent from mw::log library shall be sent via DLT using verbose mode. @@ -89,7 +89,7 @@ DLT Quotas :safety: QM :derived_from: feat_req__logging__config_buffer_size, feat_req__logging__resource_comm_channel :status: valid - :belongs_to: comp__data_router + :belongs_to: comp__datarouter The component shall have the DLT bandwidth quota configuration in the file located at ``./etc/log-channels.json`` relative to the application specific location ``/opt/``. @@ -101,7 +101,7 @@ DLT Quotas :safety: QM :derived_from: feat_req__logging__message_loss_handling, feat_req__logging__qos_message_handling :status: valid - :belongs_to: comp__data_router + :belongs_to: comp__datarouter It shall be possible to configure the action to drop DLT messages when a quota is exceeded. diff --git a/docs/components/mw_log/architecture/index.rst b/docs/components/mw_log/architecture/index.rst deleted file mode 100644 index 36bcaab5..00000000 --- a/docs/components/mw_log/architecture/index.rst +++ /dev/null @@ -1,6 +0,0 @@ -mw::log Architecture -============================ - -The backend composition and recorder relationships are shown below: - -.. uml:: ../../../../score/mw/log/design/backend/mw_log_recorders.puml diff --git a/docs/components/mw_log/detailed_design/index.rst b/docs/components/mw_log/detailed_design/index.rst index 76a546f4..ac686185 100644 --- a/docs/components/mw_log/detailed_design/index.rst +++ b/docs/components/mw_log/detailed_design/index.rst @@ -1,6 +1,10 @@ mw::log backend Detailed Design =============================== +The backend composition and recorder relationships are shown below: + +.. uml:: ../../../../score/mw/log/design/backend/mw_log_recorders.puml + .. toctree:: :maxdepth: 1 diff --git a/docs/components/mw_log/index.rst b/docs/components/mw_log/index.rst index 37c9926e..fd85dc2b 100644 --- a/docs/components/mw_log/index.rst +++ b/docs/components/mw_log/index.rst @@ -28,26 +28,14 @@ mw::log implementations. The logging component is designed to be extensible, allowing supported as well as custom logging backend to be added as needed. - The ``mw::log`` implementation spans two repositories: - - ``score_baselibs/score/mw/log`` provides the frontend API, console backend, and static recorder composition. - - ``score_logging/score/mw/log`` provides concrete file, remote/DLT, and slog recorders together with their backend - integration artifacts. - - Both repositories own their own safety plan, phase gates, and governance. The - cross-repository contract is the Recorder interface and static ``backend_table`` - registration. The existing C ABI seam is not used for static composition. - Runtime plugin loading remains experimental and is not a supported - production capability. - - .. uml:: mw_log_repository_boundary.puml + The ``mw::log`` implementation spans the ``score_baselibs`` (frontend) and ``score_logging`` (backend) + repositories; see the :doc:`feature architecture ` for the repository boundary + and cross-repository contract. .. toctree:: :titlesonly: :maxdepth: 1 - requirements - architecture/index + requirements/index detailed_design/index design_decisions/explicit_init diff --git a/docs/components/mw_log/requirements.rst b/docs/components/mw_log/requirements/index.rst similarity index 100% rename from docs/components/mw_log/requirements.rst rename to docs/components/mw_log/requirements/index.rst diff --git a/docs/components/mw_log/mw_log_repository_boundary.puml b/docs/features/architecture/_assets/mw_log_repository_boundary.puml similarity index 100% rename from docs/components/mw_log/mw_log_repository_boundary.puml rename to docs/features/architecture/_assets/mw_log_repository_boundary.puml diff --git a/docs/features/architecture/_assets/remote_logging.puml b/docs/features/architecture/_assets/remote_logging.puml new file mode 100644 index 00000000..c56c875e --- /dev/null +++ b/docs/features/architecture/_assets/remote_logging.puml @@ -0,0 +1,107 @@ +@startuml "Remote Logging High-level Overview" + +skinparam linetype ortho + +skinparam component { + BackgroundColor<> #E8F4FA + BackgroundColor<> #FDEBD0 +} +skinparam node { + BackgroundColor<> #FDEBD0 +} + +frame "ECU" { + together { + node FeatureApplication <> { + component ApplicationLogic + package "mw::log lib" as lt1 { + component "Frontend API\n(Logger, LogStream, TRACE)" as lt1_frontend <> + component "Remote Backend" as lt1_backend <> { + component "/dev/shmem/fa_*" as shmem_fa <> + } + lt1_frontend ..> lt1_backend : registers as\nbackend/recorder + } + + ApplicationLogic --> lt1_frontend : verbose <> + ApplicationLogic --> lt1_frontend : non-verbose <> + } + + node SystemApplication <> { + component SystemApplicationLogic + package "mw::log lib" as lt2 { + component "Frontend API\n(Logger, LogStream, TRACE)" as lt2_frontend <> + component "Remote Backend" as lt2_backend <> { + component "/dev/shmem/sa_*" as shmem_sa <> + } + lt2_frontend ..> lt2_backend : registers as\nbackend/recorder + } + + SystemApplicationLogic --> lt2_frontend : verbose <> + } + + node RustApplication <> { + component RustApplicationLogic + package "score_log + bridge" as lt3 { + component "score_log Facade\n(score_log, score_log_fmt)" as lt3_frontend <> + component "score_log_bridge\n(adapter.cpp)" as lt3_bridge <> + component "Remote Backend" as lt3_backend <> { + component "/dev/shmem/ra_*" as shmem_ra <> + } + lt3_frontend ..> lt3_bridge : implements\nLog trait + lt3_bridge ..> lt3_backend : FFI, direct static link\n(Runtime::GetRecorder) + } + + RustApplicationLogic --> lt3_frontend : score_log! macros\n(info!, error!, ...) + } + } + note top of SystemApplication + E.g.: StartupManager, etc. + end note + + node Datarouter <> <> { + node SourceSession1 { + } + node SourceSession2 { + } + node SourceSession3 { + } + } + + package "Operating System" { + node NetworkStack <> { + + } + } +} + +lt1_backend ..> shmem_fa : write +lt2_backend ..> shmem_sa : write +lt3_backend ..> shmem_ra : write + +shmem_fa <.. Datarouter : read +shmem_sa <.. Datarouter : read +shmem_ra <.. Datarouter : read + +FeatureApplication -[hidden]right-> SystemApplication +SystemApplication -[hidden]right-> RustApplication +FeatureApplication -[hidden]down-> Datarouter +SystemApplication -[hidden]down-> Datarouter +RustApplication -[hidden]down-> Datarouter +lt1_backend -[hidden]down-> SourceSession1 +lt2_backend -[hidden]down-> SourceSession2 +lt3_backend -[hidden]down-> SourceSession3 + +lt1_backend <-0)-> SourceSession1 : message_passing +lt2_backend <-0)-> SourceSession2 : message_passing +lt3_backend <-0)-> SourceSession3 : message_passing + +Datarouter -(0-> [NetworkStack]: socket +[NetworkStack] -r-> Multicast: sends UDP multicast + +legend right + |Color| Repository | Contents | + |<#E8F4FA>| **score_baselibs** | mw::log frontend API (Logger, LogStream, TRACE) | + |<#FDEBD0>| **score_logging** | mw::log remote backend (shmem writer) + datarouter daemon | +endlegend + +@enduml diff --git a/docs/features/architecture/index.rst b/docs/features/architecture/index.rst new file mode 100644 index 00000000..de445186 --- /dev/null +++ b/docs/features/architecture/index.rst @@ -0,0 +1,67 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + +Logging Feature Architecture +============================= + +The logging feature has two parts: the ``mw::log`` library that applications +link against and ship as part of their own binary, and the ``datarouter`` +daemon that runs as its own process. Applications never talk to ``datarouter`` +directly; ``mw::log``'s remote backend writes log records into a shared-memory +segment and hands control over to ``datarouter`` through a shared-memory and +`mw::com message-passing `_ +session; guaranteeing Freedom from interference (FFI) for the application and its +logging subsystem. Rust applications reach that same remote backend too, via +the ``score_log_bridge`` described below, so ``datarouter`` sees one uniform +set of sessions regardless of which frontend produced them. + +mw::log +------- + +The ``mw::log`` library spans across two repositories: + +``score_baselibs/score/mw/log`` provides the Cpp frontend API, console backend, static recorder composition and +the ``score_log`` Rust facade that gives Rust code the same API surface, modelled on Rust's own ``log`` crate. +This allows `baselibs `_ and `mw::com `_ +to log to the same backends as applications, and providing a common logging API for all +components. The library is linked into applications and shipped as part of their binary. + +``score_logging/score/mw/log`` provides concrete file, remote/DLT, and slog +recorders, plus the ``score_log_bridge`` that implements score_log +`Log` trait and forwards records over FFI into those same +recorders, so a Rust application ends up writing through the identical +remote backend. + +Both repositories own their own safety plan, phase gates, and governance. The +cross-repository contract is the Recorder interface and static ``backend_table`` +registration. The existing C ABI seam is not used for static composition. +Runtime plugin loading remains experimental and is not a supported +production capability. + +.. uml:: _assets/mw_log_repository_boundary.puml + +Datarouter +---------- + +The Datarouter is the Diagnostic log and trace (DLT) daemon. +See :doc:`the Datarouter component ` +for its requirements and detailed design. + +The diagram highlights the logging components and traces the +remote DLT path a log message takes once it leaves an application, including +a Rust application whose ``score_log_bridge`` registers as a recorder the same +way the C++ remote backend does and writes into its own shared-memory segment +for ``datarouter`` to read. + +.. uml:: _assets/remote_logging.puml diff --git a/docs/guides/configuration.md b/docs/guides/configuration.md deleted file mode 120000 index f58bd44a..00000000 --- a/docs/guides/configuration.md +++ /dev/null @@ -1 +0,0 @@ -../../score/datarouter/doc/guideline/configuration.md \ No newline at end of file diff --git a/docs/guides/dlt_capture_demo.md b/docs/guides/dlt_capture_demo.md deleted file mode 120000 index dfaa073c..00000000 --- a/docs/guides/dlt_capture_demo.md +++ /dev/null @@ -1 +0,0 @@ -../../score/datarouter/doc/guideline/dlt_capture_demo.md \ No newline at end of file diff --git a/docs/guides/etc/log-channels.json b/docs/guides/etc/log-channels.json deleted file mode 120000 index f4c574d9..00000000 --- a/docs/guides/etc/log-channels.json +++ /dev/null @@ -1 +0,0 @@ -../../../score/datarouter/doc/guideline/etc/log-channels.json \ No newline at end of file diff --git a/docs/guides/etc/logging.json b/docs/guides/etc/logging.json deleted file mode 120000 index 4a712e68..00000000 --- a/docs/guides/etc/logging.json +++ /dev/null @@ -1 +0,0 @@ -../../../score/datarouter/doc/guideline/etc/logging.json \ No newline at end of file diff --git a/docs/guides/file_based_local.md b/docs/guides/file_based_local.md deleted file mode 120000 index fd403042..00000000 --- a/docs/guides/file_based_local.md +++ /dev/null @@ -1 +0,0 @@ -../../score/datarouter/doc/guideline/file_based_local.md \ No newline at end of file diff --git a/docs/guides/index.rst b/docs/guides/index.rst deleted file mode 100644 index f27282e4..00000000 --- a/docs/guides/index.rst +++ /dev/null @@ -1,14 +0,0 @@ -Userguide ------------ - -Start with the `mw::log Usage Guide `_ to learn how to instrument your application with the logging API. - -The guides below then walk through configuration and typical logging setups, from basic to advanced: - -.. toctree:: - :titlesonly: - :maxdepth: 1 - - configuration - file_based_local - dlt_capture_demo diff --git a/docs/index.rst b/docs/index.rst index 5d3358ad..94aa94f1 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -53,6 +53,15 @@ The logging module includes the following top-level structure: - ``tools/``: developer-tooling - ``.github/workflows/``: CI/CD pipelines +Architecture +------------ + +.. toctree:: + :titlesonly: + :maxdepth: 1 + + features/architecture/index + Components ---------- @@ -105,7 +114,7 @@ Stats :titlesonly: :maxdepth: 1 - logging/stats.rst + verification_report/stats.rst Guides --------- @@ -114,4 +123,4 @@ Guides :titlesonly: :maxdepth: 1 - guides/index + module/manuals/index diff --git a/docs/module/manuals/config/configuration.md b/docs/module/manuals/config/configuration.md new file mode 120000 index 00000000..30e49d0a --- /dev/null +++ b/docs/module/manuals/config/configuration.md @@ -0,0 +1 @@ +../../../../score/datarouter/doc/guideline/configuration.md \ No newline at end of file diff --git a/docs/module/manuals/config/etc/log-channels.json b/docs/module/manuals/config/etc/log-channels.json new file mode 120000 index 00000000..abc7fdde --- /dev/null +++ b/docs/module/manuals/config/etc/log-channels.json @@ -0,0 +1 @@ +../../../../../score/datarouter/doc/guideline/etc/log-channels.json \ No newline at end of file diff --git a/docs/module/manuals/config/etc/logging.json b/docs/module/manuals/config/etc/logging.json new file mode 120000 index 00000000..7c916076 --- /dev/null +++ b/docs/module/manuals/config/etc/logging.json @@ -0,0 +1 @@ +../../../../../score/datarouter/doc/guideline/etc/logging.json \ No newline at end of file diff --git a/docs/module/manuals/examples/dlt_capture_demo.md b/docs/module/manuals/examples/dlt_capture_demo.md new file mode 120000 index 00000000..44e8f425 --- /dev/null +++ b/docs/module/manuals/examples/dlt_capture_demo.md @@ -0,0 +1 @@ +../../../../score/datarouter/doc/guideline/dlt_capture_demo.md \ No newline at end of file diff --git a/docs/module/manuals/examples/file_based_local.md b/docs/module/manuals/examples/file_based_local.md new file mode 120000 index 00000000..a9f4d2e1 --- /dev/null +++ b/docs/module/manuals/examples/file_based_local.md @@ -0,0 +1 @@ +../../../../score/datarouter/doc/guideline/file_based_local.md \ No newline at end of file diff --git a/docs/module/manuals/index.rst b/docs/module/manuals/index.rst new file mode 100644 index 00000000..d3343ea8 --- /dev/null +++ b/docs/module/manuals/index.rst @@ -0,0 +1,28 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + +Manuals +======= + +Start with the `mw::log Usage Guide `_ to learn how to instrument your application with the logging API. + +The guides below then walk through configuration and typical logging setups, from basic to advanced: + +.. toctree:: + :titlesonly: + :maxdepth: 1 + + config/configuration + examples/file_based_local + examples/dlt_capture_demo diff --git a/docs/logging/stats.rst b/docs/verification_report/stats.rst similarity index 100% rename from docs/logging/stats.rst rename to docs/verification_report/stats.rst diff --git a/score/datarouter/doc/design/remote_logging.plantuml b/score/datarouter/doc/design/remote_logging.plantuml index 91c73048..5e25c38f 100644 --- a/score/datarouter/doc/design/remote_logging.plantuml +++ b/score/datarouter/doc/design/remote_logging.plantuml @@ -1,69 +1,85 @@ -@startuml -title Remote Logging High-level Overview +@startuml "Remote Logging High-level Overview" -frame "ECU" { - node FeatureApplication <> { - component ApplicationLogic - component "mw::log lib" as lt1 { - component "/dev/shmem/fa_*" as shmem_fa <> - } +skinparam linetype ortho - ApplicationLogic --> lt1 : verbose <> - ApplicationLogic --> lt1 : non-verbose <> - } +skinparam component { + BackgroundColor<> #E8F4FA + BackgroundColor<> #FDEBD0 +} +skinparam node { + BackgroundColor<> #FDEBD0 +} - node SystemApplication <> { - component SystemApplicationLogic - component "mw::log lib" as lt2 { - component "/dev/shmem/sa_*" as shmem_sa <> +frame "ECU" { + together { + node FeatureApplication <> { + component ApplicationLogic + package "mw::log lib" as lt1 { + component "Frontend API\n(Logger, LogStream, TRACE)" as lt1_frontend <> + component "Remote Backend" as lt1_backend <> { + component "/dev/shmem/fa_*" as shmem_fa <> + } + lt1_frontend ..> lt1_backend : registers as\nbackend/recorder + } + + ApplicationLogic --> lt1_frontend : verbose <> + ApplicationLogic --> lt1_frontend : non-verbose <> } - SystemApplicationLogic --> lt2 : verbose <> + node SystemApplication <> { + component SystemApplicationLogic + package "mw::log lib" as lt2 { + component "Frontend API\n(Logger, LogStream, TRACE)" as lt2_frontend <> + component "Remote Backend" as lt2_backend <> { + component "/dev/shmem/sa_*" as shmem_sa <> + } + lt2_frontend ..> lt2_backend : registers as\nbackend/recorder + } + + SystemApplicationLogic --> lt2_frontend : verbose <> + } } note top of SystemApplication E.g.: StartupManager, etc. end note - node Datarouter <> { + node Datarouter <> <> { + node SourceSession1 { + } + node SourceSession2 { + } } - note left of Datarouter - Central logging daemon - end note package "Operating System" { node NetworkStack <> { } } - - node Subscriber1 { - - } - - note left of Subscriber1 - Data consumer, - e.g., PersistentLogger, etc. - end note - } -lt1 ..> shmem_fa : write -lt2 ..> shmem_sa : write +lt1_backend ..> shmem_fa : write +lt2_backend ..> shmem_sa : write shmem_fa <.. Datarouter : read shmem_sa <.. Datarouter : read -Datarouter <-0)-> Subscriber1 +FeatureApplication -[hidden]right-> SystemApplication +FeatureApplication -[hidden]down-> Datarouter +SystemApplication -[hidden]down-> Datarouter +lt1_backend -[hidden]down-> SourceSession1 +lt2_backend -[hidden]down-> SourceSession2 -note as n1 - publish/subscribe - interface -end note -n1 .. Datarouter -n1 .. Subscriber1 +lt1_backend <-0)-> SourceSession1 : message_passing +lt2_backend <-0)-> SourceSession2 : message_passing Datarouter -(0-> [NetworkStack]: socket [NetworkStack] -r-> Multicast: sends multicast +legend right + |Color| Repository | Contents | + |<#E8F4FA>| **score_baselibs** | mw::log frontend API (Logger, LogStream, TRACE) | + |<#FDEBD0>| **score_logging** | mw::log remote backend (shmem writer) + datarouter daemon | +endlegend + @enduml diff --git a/score/datarouter/doc/design/uml/context-highlevel.puml b/score/datarouter/doc/design/uml/context-highlevel.puml index 4d57073e..30d40688 100644 --- a/score/datarouter/doc/design/uml/context-highlevel.puml +++ b/score/datarouter/doc/design/uml/context-highlevel.puml @@ -1,16 +1,14 @@ -@startuml +@startuml context-highlevel -title Implementation approach - -frame "Adaptive AUTOSAR ECU" { +frame "ECU" { node AdaptiveApplication { component ApplicationLogic - interface "mw::log" as aralog1 - component "mw::log implementation" as aralog1_impl + interface "mw::log" as mwlog1 + component "mw::log implementation" as mwlog1_impl - aralog1 - aralog1_impl - ApplicationLogic --> aralog1 : verbose - ApplicationLogic --> aralog1 : non-verbose + mwlog1 - mwlog1_impl + ApplicationLogic --> mwlog1 : verbose + ApplicationLogic --> mwlog1 : non-verbose } note right of AdaptiveApplication @@ -22,29 +20,28 @@ frame "Adaptive AUTOSAR ECU" { node SystemApplication { component SystemApplicationLogic - interface "mw::log" as aralog2 - component "mw::log implementation" as aralog2_impl + interface "mw::log" as mwlog2 + component "mw::log implementation" as mwlog2_impl - aralog2 - aralog2_impl - SystemApplicationLogic --> aralog2 : verbose + mwlog2 - mwlog2_impl + SystemApplicationLogic --> mwlog2 : verbose } note right of SystemApplication - e.g. SOME/IP daemon, - ABAC component, etc. + e.g. StartupApp end note node Datarouter { } note right of Datarouter - central logging daemon + DLT logging daemon end note } boundary "UDP Multicast" as udp -aralog1_impl --> Datarouter : write -aralog2_impl --> Datarouter : write +mwlog1_impl --> Datarouter : write +mwlog2_impl --> Datarouter : write Datarouter --> udp: "send DLT messages:"