...
ONAP Application Logging Specification v1.2 (Casablanca)#HowtoLog
Issues/Decisions
# | Issue/Decision | Notes | Decision |
---|---|---|---|
1 | Are the logging guidelines set by the Logging Enhancement Project suitable for a cloud environment? | ||
2 | Do we need a second appender for errors? | Meeting Notes 11/12/20 The logging enhancement team has proposed to split the log to multiple files:
Toine has suggested we follow this approach but exclude error logging. Before making anymore decisions we will investigate this project as we have some concerns about the logging standards in the logging enhancement project. | |
3 | The application should only logs to stdout and not in files? |
| Meeting Notes 11/12/20
|
4 | Is the file location ok? | ../log/${logName}.log I think this is ok. Logs will be placed in pods once deployed. I think we will need to set a property in our SpringBootApplication class for the log dir. |
5 | Disk space | <property name="maxFileSize" value="20MB" /> Once the log reaches this value it is zipped. | |
6 | What kind of message should go with which level for logging? | See 'Summary of each logging level' below Could consider a (CPSException) property that differentiate between error/warning and even fatal if we want? | Business logic exceptions will be logged in an audit log (future) For now we will add them at a lower logging level if you feel like the log is helpful - it depends on case e.g. If the user tries to add an anchor with no dataspace we will log "Dataspace does not exist". This will be logged in the place it is handled. Sonar advises to either log the exception or throw it. You should log the original exception if it provides more information. It is up to the consumer of the java API if they want to log the exception or not. In the REST API when we catch an exception we should log it as we lose a lot of information when we convert it into a HTTP response code. For business exceptions we will use error level but we will add configuration so that it is not written to the console by default. |
7 | Where exactly to log error, at source or a common central place? |
| It should be logged in the place the error is generated. |
8 | How should we format our logs? | logger.debug("No of Orders " + noOfOrder + " for client : " + client); logger.debug("No of Executions {} for clients:{}", noOfOrder , client); | logger.debug("No of Executions {} for clients:{}", noOfOrder , client); |
9 | Should we use is log.isDebugEnabled()? | I think we should if the cost of performing the log is expensive - for example if we need to build a parameter in the log | yes, we will check log level. |
10 | What kind of information to log? |
| See CPS Logging Guidelines |
Summary of each logging level
Log Level | Importance |
---|---|
Fatal | One or more key business functionalities are not working and the whole system doesn’t fulfill the business functionalities. |
Error | One or more functionalities are not working, preventing some functionalities from working correctly. |
Warn | Unexpected behavior happened inside the application, but it is continuing its work and the key business features are operating as expected. |
Info | An event happened, the event is purely informative and can be ignored during normal operations. |
Debug | A log level used for events considered to be useful during software debugging when more granular information is needed. |
Trace | A log level describing events showing step by step execution of your code that can be ignored during the standard operation, but may be useful during extended debugging sessions. |
Appenders used by ONAP Projects
EELF guidelines stipulate that an application should output log records to four separate files:
- audit
- metrics
- error
- debug
Excerpt from ONAP Application Logging Specification v1.3 (Frankfurt)
Excerpt Include | ||||
---|---|---|---|---|
|
Current Log Config
Code Block | ||
---|---|---|
|
...
| |||
<dependency> <!-- For logging --> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </dependency> |
Code Block | ||||
---|---|---|---|---|
|
...
| |||
| |||
... logging: level: org: springframework: INFO |
Code Block | |||||
---|---|---|---|---|---|
| |||||
| |||||
<configuration scan="true" debug="false"> <include resource="org/springframework/boot/logging/logback/base.xml" /> <property name="queueSize" value="256" /> <property name="maxFileSize" value="20MB" /> <property name="maxHistory" value="30" /> <property name="totalSizeCap" value="20MB" /> <!-- log file names --> <property name="logName" value="cps" /> <property name="currentTimeStamp" value="%d{"yyyy-MM-dd'T'HH:mm:ss.SSSXXX",UTC}"/> <property name="debugPattern" value="%d{yyyy-MM-dd'T'HH:mm:ss.SSSXXX}|%thread|%X{RequestID}| %logger{50} - %msg%n" /> <appender name="Debug" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>../log/${logName}.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <fileNamePattern>${logName}.%d{yyyy-MM-dd}.%i.log.zip </fileNamePattern> <maxFileSize>${maxFileSize}</maxFileSize> <maxHistory>${maxHistory}</maxHistory> <totalSizeCap>${totalSizeCap}</totalSizeCap> </rollingPolicy> <encoder> <pattern>${debugPattern}</pattern> </encoder> </appender> <appender name="asyncDebug" class="ch.qos.logback.classic.AsyncAppender"> <queueSize>256</queueSize> <appender-ref ref="Debug" /> <includeCallerData>true</includeCallerData> </appender> <logger name="org.onap.cps" level="DEBUG" additivity="false"> <appender-ref ref="asyncDebug" /> </logger> <root level="INFO"> <appender-ref ref="asyncDebug" /> </root> </configuration> |
...