1 /*
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 * All rights reserved.
4 *
5 * This source code is licensed under the BSD-style license found in the
6 * LICENSE file in the root directory of this source tree.
7 */
8
9 #include <executorch/runtime/platform/log.h>
10
11 #include <cstdio>
12
13 #include <executorch/runtime/platform/compiler.h>
14 #include <executorch/runtime/platform/platform.h>
15
16 namespace executorch {
17 namespace runtime {
18 namespace internal {
19
20 /**
21 * Get the current timestamp to construct a log event.
22 *
23 * @retval Monotonically non-decreasing timestamp in system ticks.
24 */
get_log_timestamp()25 et_timestamp_t get_log_timestamp() {
26 return et_pal_current_ticks();
27 }
28
29 // Double-check that the log levels are ordered from lowest to highest severity.
30 static_assert(LogLevel::Debug < LogLevel::Info, "");
31 static_assert(LogLevel::Info < LogLevel::Error, "");
32 static_assert(LogLevel::Error < LogLevel::Fatal, "");
33 static_assert(LogLevel::Fatal < LogLevel::NumLevels, "");
34
35 /**
36 * Maps LogLevel values to et_pal_log_level_t values.
37 *
38 * We don't share values because LogLevel values need to be ordered by severity,
39 * and et_pal_log_level_t values need to be printable characters.
40 */
41 static constexpr et_pal_log_level_t kLevelToPal[size_t(LogLevel::NumLevels)] = {
42 et_pal_log_level_t::kDebug,
43 et_pal_log_level_t::kInfo,
44 et_pal_log_level_t::kError,
45 et_pal_log_level_t::kFatal,
46 };
47
48 // Double-check that the indices are correct.
49 static_assert(
50 kLevelToPal[size_t(LogLevel::Debug)] == et_pal_log_level_t::kDebug,
51 "");
52 static_assert(
53 kLevelToPal[size_t(LogLevel::Info)] == et_pal_log_level_t::kInfo,
54 "");
55 static_assert(
56 kLevelToPal[size_t(LogLevel::Error)] == et_pal_log_level_t::kError,
57 "");
58 static_assert(
59 kLevelToPal[size_t(LogLevel::Fatal)] == et_pal_log_level_t::kFatal,
60 "");
61
62 /**
63 * Log a string message.
64 *
65 * Note: This is an internal function. Use the `ET_LOG` macro instead.
66 *
67 * @param[in] level Log severity level.
68 * @param[in] timestamp Timestamp (in system ticks) of the log event.
69 * @param[in] filename Name of the source file creating the log event.
70 * @param[in] function Name of the function creating the log event.
71 * @param[in] line Source file line of the caller.
72 * @param[in] format Format string.
73 * @param[in] args Variable argument list.
74 */
vlogf(ET_UNUSED LogLevel level,et_timestamp_t timestamp,const char * filename,ET_UNUSED const char * function,size_t line,const char * format,va_list args)75 void vlogf(
76 ET_UNUSED LogLevel level,
77 et_timestamp_t timestamp,
78 const char* filename,
79 ET_UNUSED const char* function,
80 size_t line,
81 const char* format,
82 va_list args) {
83 #if ET_LOG_ENABLED
84
85 // Maximum length of a log message.
86 static constexpr size_t kMaxLogMessageLength = 256;
87 char buf[kMaxLogMessageLength];
88 size_t len = vsnprintf(buf, kMaxLogMessageLength, format, args);
89 if (len >= kMaxLogMessageLength - 1) {
90 buf[kMaxLogMessageLength - 2] = '$';
91 len = kMaxLogMessageLength - 1;
92 }
93 buf[kMaxLogMessageLength - 1] = 0;
94
95 et_pal_log_level_t pal_level =
96 (int(level) >= 0 && level < LogLevel::NumLevels)
97 ? kLevelToPal[size_t(level)]
98 : et_pal_log_level_t::kUnknown;
99
100 et_pal_emit_log_message(
101 timestamp, pal_level, filename, function, line, buf, len);
102
103 #endif // ET_LOG_ENABLED
104 }
105
106 } // namespace internal
107 } // namespace runtime
108 } // namespace executorch
109