1 | /* Copyright 2019 The TensorFlow Authors. All Rights Reserved. |
2 | |
3 | Licensed under the Apache License, Version 2.0 (the "License"); |
4 | you may not use this file except in compliance with the License. |
5 | You may obtain a copy of the License at |
6 | |
7 | http://www.apache.org/licenses/LICENSE-2.0 |
8 | |
9 | Unless required by applicable law or agreed to in writing, software |
10 | distributed under the License is distributed on an "AS IS" BASIS, |
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | See the License for the specific language governing permissions and |
13 | limitations under the License. |
14 | ==============================================================================*/ |
15 | #ifndef TENSORFLOW_LITE_MINIMAL_LOGGING_H_ |
16 | #define TENSORFLOW_LITE_MINIMAL_LOGGING_H_ |
17 | |
18 | #include <cstdarg> |
19 | |
20 | #include "tensorflow/lite/logger.h" |
21 | |
22 | namespace tflite { |
23 | |
24 | namespace logging_internal { |
25 | |
26 | using tflite::LogSeverity; |
27 | |
28 | // Helper class for simple platform-specific console logging. Note that we |
29 | // explicitly avoid the convenience of ostream-style logging to minimize binary |
30 | // size impact. |
31 | class MinimalLogger { |
32 | public: |
33 | // Logging hook that takes variadic args. |
34 | static void Log(LogSeverity severity, const char* format, ...); |
35 | |
36 | // Logging hook that takes a formatted va_list. |
37 | static void LogFormatted(LogSeverity severity, const char* format, |
38 | va_list args); |
39 | |
40 | // Get the minimum severity level for logging. Default is INFO in prod builds |
41 | // and VERBOSE in debug builds. |
42 | // Note: Default is always VERBOSE on Android. |
43 | static LogSeverity GetMinimumLogSeverity(); |
44 | |
45 | // Set the minimum severity level for logging, returning the old severity. |
46 | static LogSeverity SetMinimumLogSeverity(LogSeverity new_severity); |
47 | |
48 | private: |
49 | static const char* GetSeverityName(LogSeverity severity); |
50 | static LogSeverity minimum_log_severity_; |
51 | }; |
52 | |
53 | } // namespace logging_internal |
54 | } // namespace tflite |
55 | |
56 | // Convenience macro for basic internal logging in production builds. |
57 | // Note: This should never be used for debug-type logs, as it will *not* be |
58 | // stripped in release optimized builds. In general, prefer the error reporting |
59 | // APIs for developer-facing errors, and only use this for diagnostic output |
60 | // that should always be logged in user builds. |
61 | #define TFLITE_LOG_PROD(severity, format, ...) \ |
62 | if (severity >= \ |
63 | ::tflite::logging_internal::MinimalLogger::GetMinimumLogSeverity()) { \ |
64 | ::tflite::logging_internal::MinimalLogger::Log(severity, format, \ |
65 | ##__VA_ARGS__); \ |
66 | } |
67 | |
68 | // Convenience macro for logging a statement *once* for a given process lifetime |
69 | // in production builds. |
70 | #define TFLITE_LOG_PROD_ONCE(severity, format, ...) \ |
71 | do { \ |
72 | static const bool s_logged = [&] { \ |
73 | TFLITE_LOG_PROD(severity, format, ##__VA_ARGS__) \ |
74 | return true; \ |
75 | }(); \ |
76 | (void)s_logged; \ |
77 | } while (false); |
78 | |
79 | #ifndef NDEBUG |
80 | // In debug builds, always log. |
81 | #define TFLITE_LOG TFLITE_LOG_PROD |
82 | #define TFLITE_LOG_ONCE TFLITE_LOG_PROD_ONCE |
83 | #else |
84 | // In prod builds, never log, but ensure the code is well-formed and compiles. |
85 | #define TFLITE_LOG(severity, format, ...) \ |
86 | while (false) { \ |
87 | TFLITE_LOG_PROD(severity, format, ##__VA_ARGS__); \ |
88 | } |
89 | #define TFLITE_LOG_ONCE TFLITE_LOG |
90 | #endif |
91 | |
92 | #endif // TENSORFLOW_LITE_MINIMAL_LOGGING_H_ |
93 | |