526fe4b18058335be3e6bf57ae41c1c4a2b1d021
[platform/upstream/connectedhomeip.git] / src / platform / nrfconnect / Logging.cpp
1 /*
2  *
3  *    Copyright (c) 2020 Project CHIP Authors
4  *
5  *    Licensed under the Apache License, Version 2.0 (the "License");
6  *    you may not use this file except in compliance with the License.
7  *    You may obtain a copy of the License at
8  *
9  *        http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *    Unless required by applicable law or agreed to in writing, software
12  *    distributed under the License is distributed on an "AS IS" BASIS,
13  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *    See the License for the specific language governing permissions and
15  *    limitations under the License.
16  */
17
18 /**
19  *    @file
20  *          Provides implementations for the CHIP logging functions
21  *          on Nordic nRF Connect SDK platforms.
22  */
23
24 #include <platform/internal/CHIPDeviceLayerInternal.h>
25 #include <support/logging/CHIPLogging.h>
26
27 #include <kernel.h>
28 #include <logging/log.h>
29
30 #include <cstdio>
31
32 using namespace ::chip;
33 using namespace ::chip::DeviceLayer;
34 using namespace ::chip::DeviceLayer::Internal;
35
36 LOG_MODULE_REGISTER(chip, LOG_LEVEL_DBG);
37
38 namespace chip {
39 namespace DeviceLayer {
40
41 /**
42  * Called whenever a log message is emitted by chip.
43  *
44  * This function is intended be overridden by the application to, e.g.,
45  * schedule output of queued log entries.
46  */
47 void __attribute__((weak)) OnLogOutput(void) {}
48
49 } // namespace DeviceLayer
50
51 namespace Logging {
52
53 /**
54  * CHIP log output function.
55  */
56
57 void LogV(uint8_t module, uint8_t category, const char * msg, va_list v)
58 {
59     if (!IsCategoryEnabled(category))
60         return;
61
62     {
63         char formattedMsg[CHIP_DEVICE_CONFIG_LOG_MESSAGE_MAX_SIZE];
64         size_t prefixLen = 0;
65
66         // Max size for "[TAG] {UINT32}"
67         constexpr size_t maxPrefixLen = ChipLoggingModuleNameLen + 10 + 3;
68         static_assert(sizeof(formattedMsg) > maxPrefixLen);
69
70         prefixLen += snprintf(formattedMsg, sizeof(formattedMsg), "%u", k_uptime_get_32());
71
72         // Form the log prefix, e.g. "[DL] "
73         formattedMsg[prefixLen++] = '[';
74         GetModuleName(formattedMsg + prefixLen, module);
75         prefixLen                 = strlen(formattedMsg);
76         formattedMsg[prefixLen++] = ']';
77         formattedMsg[prefixLen++] = ' ';
78
79         // Append the log message.
80         vsnprintf(formattedMsg + prefixLen, sizeof(formattedMsg) - prefixLen, msg, v);
81
82         // Invoke the Zephyr logging library to log the message.
83         //
84         // Unfortunately the Zephyr logging macros end up assigning uint16_t
85         // variables to uint16_t:10 fields, which triggers integer conversion
86         // warnings.  And treating the Zephyr headers as system headers does not
87         // help, apparently.  Just turn off that warning around this switch.
88 #pragma GCC diagnostic push
89 #pragma GCC diagnostic ignored "-Wconversion"
90         switch (category)
91         {
92         case kLogCategory_Error:
93             LOG_ERR("%s", log_strdup(formattedMsg));
94             break;
95         case kLogCategory_Progress:
96         case kLogCategory_Retain:
97         default:
98             LOG_INF("%s", log_strdup(formattedMsg));
99             break;
100         case kLogCategory_Detail:
101             LOG_DBG("%s", log_strdup(formattedMsg));
102             break;
103         }
104 #pragma GCC diagnostic pop
105     }
106
107     // Let the application know that a log message has been emitted.
108     DeviceLayer::OnLogOutput();
109 }
110
111 } // namespace Logging
112 } // namespace chip