Skip to content

Commit

Permalink
Merge pull request #1358 from ApexAI/iox-#1345-logging-design-document
Browse files Browse the repository at this point in the history
iox-#1345 Design document for logging
  • Loading branch information
elBoberido authored Nov 9, 2022
2 parents e776718 + 3401bc8 commit 6b349c2
Show file tree
Hide file tree
Showing 39 changed files with 795 additions and 89 deletions.
2 changes: 1 addition & 1 deletion .clang-tidy-diff-scans.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
./iceoryx_hoofs/test/moduletests/test_log*
./iceoryx_hoofs/test/moduletests/test_console_logger*
./iceoryx_hoofs/testing/include/iceoryx_hoofs/testing/mocks/logger_mock.hpp
./iceoryx_hoofs/testing/include/iceoryx_hoofs/testing/logger.hpp
./iceoryx_hoofs/testing/include/iceoryx_hoofs/testing/testing_logger.hpp
./iceoryx_hoofs/testing/logger.cpp

./iceoryx_hoofs/include/iceoryx_hoofs/internal/posix_wrapper/shared_memory_object/*
Expand Down
28 changes: 28 additions & 0 deletions doc/design/diagrams/logging/logger_compile_time_replacement.puml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
@startuml

participant User
participant Logger << static >>
participant "logger : Logger" as loggerInstance

User -> Logger ++ : init

Logger -> Logger ++ : get
Logger -> Logger ++ : activeLogger
Logger -> loggerInstance **
note over loggerInstance
the default logger
is configured via
the alias in
log/logger.hpp
end note
return
return

Logger -> loggerInstance ++ : initLoggerInternal
loggerInstance -> loggerInstance ++ : initLogger
return
return

return

@enduml
49 changes: 49 additions & 0 deletions doc/design/diagrams/logging/logger_runtime_replacement.puml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
@startuml

participant User
participant MyLogger << static >>
participant Logger << static >>
participant "logger : Logger" as loggerInstance
participant "myLogger : MyLogger" as myLoggerInstance

User -> MyLogger ++ : init
MyLogger -> myLoggerInstance **
MyLogger -> Logger ++ : setActiveLogger(&myLogger)
Logger -> Logger ++ : activeLogger(&myLogger)
note left Logger
the static pointer
to the active logger
will be set to
myLogger
end note

Logger -> loggerInstance **
note over loggerInstance
calling activeLogger
without parameter
will create this anyway
(e.g. by logging before
calling initLogger)
so there is no need
to to make it more
complicated by
branching
end note

return
return

MyLogger -> Logger ++ : init
Logger -> Logger ++ : get
Logger -> Logger ++ : activeLogger()
return
return
Logger -> loggerInstance ++ : initLoggerInternal
loggerInstance -> myLoggerInstance ++ : initLogger
return
return
return

return

@enduml
29 changes: 29 additions & 0 deletions doc/design/diagrams/logging/logger_testing_classes.puml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
@startuml

class TestingLoggerBase
note bottom
type alias to 'Logger<BaseLogger>' with
specific 'BaseLogger' implementation
end note

package testing <<Frame>> {
class TestingLogger {
}
class LogPrinter {
+ void OnTestStart(const ::testing::TestInfo&)
+ void OnTestPartResult(const ::testing::TestPartResult& result)
}
}

package gTest <<Frame>> {
class ::testing::EmptyTestEventListener {
}
class ::testing::UnitTest {
}
}

TestingLogger --|> TestingLoggerBase
LogPrinter .> TestingLogger : <<uses>>
LogPrinter --|> ::testing::EmptyTestEventListener

@enduml
42 changes: 42 additions & 0 deletions doc/design/diagrams/logging/logger_testing_sequence.puml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
@startuml

participant User
participant TestingLogger << static >>
participant Logger << static >>
participant "logger : TestingLogger" as testingLoggerInstance
participant LogPrinter
participant gTest
participant UnitTest
participant TestEventListener

User -> TestingLogger ++ : init
TestingLogger -> testingLoggerInstance **
TestingLogger -> Logger ++: setActiveLogger
return
TestingLogger -> Logger ++: init
return
TestingLogger -> UnitTest ++ : listeners
return
TestingLogger -> TestEventListener ++ : Append(LogPrinter*)
return
return

User -> gTest ++ : RUN_ALL_TESTS

gTest -> LogPrinter ++ : OnTestStart
LogPrinter -> Logger ++: get
return
LogPrinter -> testingLoggerInstance ++ : clearLogBuffer
return
return

gTest -> LogPrinter ++ : OnTestPartResult
LogPrinter -> Logger ++: get
return
LogPrinter -> testingLoggerInstance ++ : printLogBuffer
return
return

return

@enduml
82 changes: 82 additions & 0 deletions doc/design/diagrams/logging/logging_classes.puml
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
@startuml

package building_blocks <<Frame>> {

enum LogLevel {
OFF = 0,
FATAL,
ERROR,
WARN,
INFO,
DEBUG,
TRACE,
}

class Logger <BaseLogger> {
+ {static} void init(const LogLevel logLevel = LogLevelFromEnvOr(LogLevel::Info))
+ {static} Logger& get()
+ {static} void setActiveLogger(Logger* newLogger)
- void initLoggerInternal(LogLevel logLevel)
- {static} Logger& activeLogger(Logger* newLogger = nullptr)
}

class ConsoleLogger {
+ {static} LogLevel getLogLevel()
+ {static} void setLogLevel(LogLevel logLevel)
# ConsoleLogger()
# {abstract} void initLogger(LogLevel logLevel)
# {abstract} void createLogMessageHeader(const char* file, const int line, const char* function, LogLevel logLevel)
# {abstract} void flush()
# LogBuffer getLogBuffer() const
# void assumeFlushed()
# void logString(const char* message)
# void logBool(const bool value)
# void logDec(const T value) with T being arithmetic types
# void logHex(const T value) with T being unsigned integers, floats or pointer
# void logOct(const T value) with T being unsigned integers
}

}

package testing <<Frame>> {

class TestingLogger {
+ {static} void init()
+ {static} uint64_t getNumberOfLogMessages()
+ {static} std::vector<std::string> getLogMessages()
+ {static} bool doesLoggerSupportLogLevel(const LogLevel logLevel)
+ void clearLogBuffer()
+ void printLogBuffer()
- void TestingLogger()
- void flush()
}

}

class LogHex <T> {}

class LogOct <T> {}

class LogStream {
+ LogStream(const char* file, const int line, const char* function, LogLevel logLevel)
+ LogStream(Logger& logger, const char* file, const int line, const char* function, LogLevel logLevel)
+ LogStream(const char* file, const int line, const char* function, LogLevel logLevel, bool doFlush)
+ LogStream& self()
+ LogStream& operator<<(const char* cstr)
+ LogStream& operator<<(const std::string& str)
+ LogStream& operator<<(const bool val)
+ LogStream& operator<<(const T value) with T being arithmetic types
+ LogStream& operator<<(const LogHex<T> val) with T being integers and floats
+ LogStream& operator<<(const LogHex<const void * const> val)
+ LogStream& operator<<(const LogOct<T> val) with T being integers
+ LogStream& operator<<(const Callable& c) with signature 'LogStream&(LogStream&)'
- void flush()
}

ConsoleLogger <|-- Logger : via BaseLogger
Logger <|-- TestingLogger
Logger <.. LogStream : <<friend>>
LogStream ..> LogHex : <<friend>>
LogStream ..> LogOct : <<friend>>

@enduml
41 changes: 41 additions & 0 deletions doc/design/diagrams/logging/logging_with_logstream.puml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
@startuml

participant User
participant LogStream
participant Logger << static >>
participant "logger : Logger" as loggerInstance

User -> LogStream ** : IOX_LOG(...)
activate LogStream
LogStream -> Logger ++ : get
Logger -> Logger ++ : activeLogger()
note right
activeLogger is only called
to initialize the thread local
logger pointer or when the
active flag of the logger is false
end note

Logger -> Logger : std::lock
Logger -> loggerInstance **

return
return

LogStream -> loggerInstance ++ : createLogMessageHeader
return

return

User -> LogStream ++ : << Hello World
LogStream -> loggerInstance ++ : logString
return
return

User -> LogStream ++ : dTor via ; on temporary
LogStream -> loggerInstance ++ : flush
return
return
destroy LogStream

@enduml
Loading

0 comments on commit 6b349c2

Please sign in to comment.