1/*
2 * Copyright (c) 2015 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24#ifndef __os_log_h
25#define __os_log_h
26
27#include <os/object.h>
28#include <stdint.h>
29#include <stdbool.h>
30
31#ifndef __has_attribute
32#define __has_attribute(x) 0
33#endif
34
35#ifndef __has_builtin
36#define __has_builtin(x) 0
37#endif
38
39#if __has_attribute(not_tail_called)
40#define OS_LOG_NOTAILCALL __attribute__((not_tail_called))
41#define OS_LOG_NOTAILCALL_MARKER
42#else
43#define OS_LOG_NOTAILCALL
44#define OS_LOG_NOTAILCALL_MARKER __asm__("")
45#endif
46
47__BEGIN_DECLS
48
49extern void *__dso_handle;
50
51#ifdef XNU_KERNEL_PRIVATE
52extern bool startup_serial_logging_active;
53extern uint64_t startup_serial_num_procs;
54#endif /* XNU_KERNEL_PRIVATE */
55
56OS_ALWAYS_INLINE static inline void _os_log_verify_format_str(__unused const char *msg, ...) __attribute__((format(os_log, 1, 2)));
57OS_ALWAYS_INLINE static inline void _os_log_verify_format_str(__unused const char *msg, ...) { /* placeholder */ }
58
59#if OS_OBJECT_USE_OBJC
60OS_OBJECT_DECL(os_log);
61#else
62typedef struct os_log_s *os_log_t;
63#endif /* OS_OBJECT_USE_OBJC */
64
65/*!
66 * @const OS_LOG_DISABLED
67 *
68 * @discussion
69 * Use this to disable a specific log message.
70 */
71#define OS_LOG_DISABLED NULL
72
73/*!
74 * @const OS_LOG_DEFAULT
75 *
76 * @discussion
77 * Use this to log a message in accordance with current system settings.
78 */
79#define OS_LOG_DEFAULT OS_OBJECT_GLOBAL_OBJECT(os_log_t, _os_log_default)
80__OSX_AVAILABLE_STARTING(__MAC_10_12,__IPHONE_10_0)
81OS_EXPORT
82struct os_log_s _os_log_default;
83
84/*!
85 * @enum os_log_type_t
86 *
87 * @discussion
88 * Supported log message types.
89 *
90 * @constant OS_LOG_TYPE_DEFAULT
91 * Equivalent type for "os_log()" messages, i.e., default messages that are always
92 * captured to memory or disk.
93 *
94 * @constant OS_LOG_TYPE_INFO
95 * Equivalent type for "os_log_info()" messages, i.e., Additional informational messages.
96 *
97 * @constant OS_LOG_TYPE_DEBUG
98 * Equivalent type for "os_log_debug()" messages, i.e., Debug messages.
99 *
100 * @constant OS_LOG_TYPE_ERROR
101 * Equivalent type for "os_log_error()" messages, i.e., local process error messages.
102 *
103 * @constant OS_LOG_TYPE_FAULT
104 * Equivalent type for "os_log_fault()" messages, i.e., a system error that involves
105 * potentially more than one process, usually used by daemons and services.
106 */
107OS_ENUM(os_log_type, uint8_t,
108 OS_LOG_TYPE_DEFAULT = 0x00,
109 OS_LOG_TYPE_INFO = 0x01,
110 OS_LOG_TYPE_DEBUG = 0x02,
111 OS_LOG_TYPE_ERROR = 0x10,
112 OS_LOG_TYPE_FAULT = 0x11);
113
114/*!
115 * @function os_log_create
116 *
117 * @abstract
118 * Creates a log object to be used with other log related functions.
119 *
120 * @discussion
121 * Creates a log object to be used with other log related functions. The
122 * log object serves two purposes: (1) tag related messages by subsystem
123 * and category name for easy filtering, and (2) control logging system
124 * behavior for messages.
125 *
126 * A log object may customize logging system behavior for its messages by
127 * adding a configuration file in /Library/LogPreferences. Most options
128 * accept 3 values: "Default", "Yes" or "No" as strings, where "Default"
129 * signifies follow system behavior for the level of messages.
130 *
131 * For log:
132 *
133 * os_log_create("com.company.mysubsystem", "connections");
134 *
135 * System-provided preferences are located in /System/Library/LogPreferences/<subsystem>.plist
136 *
137 * <dict>
138 *
139 * <!-- Default options applied to message types in each category, which can be overriden. -->
140 * <key>DEFAULT-OPTIONS</key>
141 * <dict>
142 * <key>Enabled</key> <!-- Enabled state follows system defaults -->
143 * <string>Default</string>
144 * <key>Persist</key> <!-- Do not persist to disk, use memory-only buffer if enabled -->
145 * <string>No</string>
146 * <key>TTL</key> <!-- Follow system default behavior if persistence is enabled -->
147 * <string>Default</string> <!-- Can specify in days with "d" or hours "h" (e.g., "4h" = 4 hours) -->
148 * </dict>
149 *
150 * <!-- category named “connections” -->
151 * <key>connections</key>
152 * <dict>
153 *
154 * <!-- Options that control "os_log()" behavior. The "Enabled" option is ignored. -->
155 * <key>Default</key>
156 * <dict>
157 * <key>Persist</key> <!-- Always persist to disk -->
158 * <string>Yes</string>
159 * <key>TTL</key> <!-- Store default messages for maximum 4 days -->
160 * <integer>4d</integer>
161 * </dict>
162 *
163 * <!-- Subdictionary of options that control "os_log_info()" behavior -->
164 * <key>Info</key>
165 * <dict>
166 * <key>Persist</key> <!-- If enabled persist to disk -->
167 * <string>Yes</string>
168 * <key>TTL</key> <!-- Store Info messages for 2 days -->
169 * <string>2d</string>
170 * </dict>
171 *
172 * <!-- Subdictionary of options that control "os_log_debug()" behavior -->
173 * <key>Debug</key>
174 * <dict>
175 * <key>Enabled</key> <!-- Not enabled, must be enabled specifically -->
176 * <string>No</string>
177 * </dict>
178 * </dict>
179 * </dict>
180 *
181 * All other preferences and system-overrides are stored in /Library/LogPreferences/.
182 *
183 * @param subsystem
184 * The identifier of the given subsystem should be in reverse DNS form
185 * (i.e., com.company.mysubsystem). This string must be a constant string,
186 * not dynamically generated.
187 *
188 * @param category
189 * The category within the given subsystem that specifies the settings for
190 * the log object. This string must be a constant string, not dynamically
191 * generated.
192 *
193 * @result
194 * Returns an os_log_t value to be passed to other os_log API calls. This
195 * should be called once at log initialization and rely on system to detect
196 * changes to settings. This object should be released when no longer used
197 * via os_release or -[release] method.
198 *
199 * A value will always be returned to allow for dynamic enablement.
200 */
201__OSX_AVAILABLE_STARTING(__MAC_10_12,__IPHONE_10_0)
202OS_EXPORT OS_NOTHROW OS_WARN_RESULT OS_OBJECT_RETURNS_RETAINED
203os_log_t
204os_log_create(const char *subsystem, const char *category);
205
206/*!
207 * @function os_log_info_enabled
208 *
209 * @abstract
210 * Returns if development log messages are enabled for a particular log object.
211 *
212 * @discussion
213 * Returns if development log messages are enabled for a particular log object.
214 *
215 * @param log
216 * Pass OS_LOG_DEFAULT or a log object previously created with os_log_create.
217 *
218 * @result
219 * Returns ‘true’ if debug log messages are enabled.
220 */
221__WATCHOS_AVAILABLE(3.0) __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0)
222OS_EXPORT OS_NOTHROW OS_WARN_RESULT
223bool
224os_log_info_enabled(os_log_t log);
225
226/*!
227 * @function os_log_debug_enabled
228 *
229 * @abstract
230 * Returns if debug log messages are enabled for a particular log object.
231 *
232 * @discussion
233 * Returns if debug log messages are enabled for a particular log object.
234 *
235 * @param log
236 * Pass OS_LOG_DEFAULT or a log object previously created with os_log_create.
237 *
238 * @result
239 * Returns ‘true’ if debug log messages are enabled.
240 */
241__WATCHOS_AVAILABLE(3.0) __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0)
242OS_EXPORT OS_NOTHROW OS_WARN_RESULT
243bool
244os_log_debug_enabled(os_log_t log);
245
246/*!
247 * @function os_log
248 *
249 * @abstract
250 * Insert a log message into the Unified Logging and Tracing system.
251 *
252 * @discussion
253 * Insert a log message into the Unified Logging and Tracing system in
254 * accordance with the preferences specified by the provided log object.
255 * These messages cannot be disabled and therefore always captured either
256 * to memory or disk.
257 *
258 * When an os_activity_id_t is present, the log message will also be scoped by
259 * that identifier. Activities provide granular filtering of log messages
260 * across threads and processes.
261 *
262 * There is a physical cap of 256 bytes per entry for dynamic content,
263 * i.e., %s and %@, that can be written to the persistence store. As such,
264 * all content exceeding the limit will be truncated before written to disk.
265 * Live streams will continue to show the full content.
266 *
267 * @param log
268 * Pass OS_LOG_DEFAULT or a log object previously created with os_log_create.
269 *
270 * @param format
271 * A format string to generate a human-readable log message when the log
272 * line is decoded. This string must be a constant string, not dynamically
273 * generated. Supports all standard printf types and %@ (objects).
274 */
275#define os_log(log, format, ...) __extension__({ \
276 _Static_assert(__builtin_constant_p(format), "format string must be constant"); \
277 __attribute__((section("__TEXT,__os_log"))) static const char _os_log_fmt[] = format; \
278 _os_log_verify_format_str(format, ##__VA_ARGS__); \
279 _os_log_internal(&__dso_handle, log, OS_LOG_TYPE_DEFAULT, _os_log_fmt, ##__VA_ARGS__); \
280 __asm__(""); /* avoid tailcall */ \
281})
282
283/*!
284 * @function os_log_info
285 *
286 * @abstract
287 * Insert a development log message into the Unified Logging and Tracing system.
288 *
289 * @discussion
290 * Insert a log message into the Unified Logging and Tracing system in
291 * accordance with the preferences specified by the provided log object.
292 *
293 * When an os_activity_id_t is present, the log message will also be scoped by
294 * that identifier. Activities provide granular filtering of log messages
295 * across threads and processes.
296 *
297 * There is a physical cap of 256 bytes per entry for dynamic content,
298 * i.e., %s and %@, that can be written to the persistence store. As such,
299 * all content exceeding the limit will be truncated before written to disk.
300 * Live streams will continue to show the full content.
301 *
302 * @param log
303 * Pass OS_LOG_DEFAULT or a log object previously created with os_log_create.
304 *
305 * @param format
306 * A format string to generate a human-readable log message when the log
307 * line is decoded. This string must be a constant string, not dynamically
308 * generated. Supports all standard printf types and %@ (objects).
309 */
310#define os_log_info(log, format, ...) __extension__({ \
311 _Static_assert(__builtin_constant_p(format), "format string must be constant"); \
312 __attribute__((section("__TEXT,__os_log"))) static const char _os_log_fmt[] = format; \
313 _os_log_verify_format_str(format, ##__VA_ARGS__); \
314 _os_log_internal(&__dso_handle, log, OS_LOG_TYPE_INFO, _os_log_fmt, ##__VA_ARGS__); \
315 __asm__(""); /* avoid tailcall */ \
316})
317
318/*!
319 * @function os_log_debug
320 *
321 * @abstract
322 * Insert a debug log message into the Unified Logging and Tracing system.
323 *
324 * @discussion
325 * Insert a debug log message into the Unified Logging and Tracing system in
326 * accordance with the preferences specified by the provided log object.
327 *
328 * When an os_activity_id_t is present, the log message will also be scoped by
329 * that identifier. Activities provide granular filtering of log messages
330 * across threads and processes.
331 *
332 * There is a physical cap of 256 bytes per entry for dynamic content,
333 * i.e., %s and %@, that can be written to the persistence store. As such,
334 * all content exceeding the limit will be truncated before written to disk.
335 * Live streams will continue to show the full content.
336 *
337 * @param log
338 * Pass OS_LOG_DEFAULT or a log object previously created with os_log_create.
339 *
340 * @param format
341 * A format string to generate a human-readable log message when the log
342 * line is decoded. This string must be a constant string, not dynamically
343 * generated. Supports all standard printf types and %@ (objects).
344 */
345#define os_log_debug(log, format, ...) __extension__({ \
346 _Static_assert(__builtin_constant_p(format), "format string must be constant"); \
347 __attribute__((section("__TEXT,__os_log"))) static const char _os_log_fmt[] = format; \
348 _os_log_verify_format_str(format, ##__VA_ARGS__); \
349 _os_log_internal(&__dso_handle, log, OS_LOG_TYPE_DEBUG, _os_log_fmt, ##__VA_ARGS__); \
350 __asm__(""); /* avoid tailcall */ \
351})
352
353/*!
354 * @function os_log_error
355 *
356 * @abstract
357 * Insert an error log message into the Unified Logging and Tracing system.
358 *
359 * @discussion
360 * Insert an error log message into the Unified Logging and Tracing system.
361 *
362 * When an os_activity_id_t is present, the log message will also be scoped by
363 * that identifier. Activities provide granular filtering of log messages
364 * across threads and processes.
365 *
366 * There is a physical cap of 256 bytes per entry for dynamic content,
367 * i.e., %s and %@, that can be written to the persistence store. As such,
368 * all content exceeding the limit will be truncated before written to disk.
369 * Live streams will continue to show the full content.
370 *
371 * @param log
372 * Pass OS_LOG_DEFAULT or a log object previously created with os_log_create.
373 *
374 * @param format
375 * A format string to generate a human-readable log message when the log
376 * line is decoded. This string must be a constant string, not dynamically
377 * generated. Supports all standard printf types and %@ (objects).
378 */
379#define os_log_error(log, format, ...) __extension__({ \
380 _Static_assert(__builtin_constant_p(format), "format string must be constant"); \
381 __attribute__((section("__TEXT,__os_log"))) static const char _os_log_fmt[] = format; \
382 _os_log_verify_format_str(format, ##__VA_ARGS__); \
383 _os_log_internal(&__dso_handle, log, OS_LOG_TYPE_ERROR, _os_log_fmt, ##__VA_ARGS__); \
384 __asm__(""); /* avoid tailcall */ \
385})
386
387/*!
388 * @function os_log_fault
389 *
390 * @abstract
391 * Insert a fault log message into the Unified Logging and Tracing system.
392 *
393 * @discussion
394 * Log a fault message issue into the Unified Logging and Tracing system
395 * signifying a multi-process (i.e., system error) related issue, either
396 * due to interaction via IPC or some other. Faults will gather information
397 * from the entire process chain and record it for later inspection.
398 *
399 * When an os_activity_id_t is present, the log message will also be scoped by
400 * that identifier. Activities provide granular filtering of log messages
401 * across threads and processes.
402 *
403 * There is a physical cap of 256 bytes per entry for dynamic content,
404 * i.e., %s and %@, that can be written to the persistence store. As such,
405 * all content exceeding the limit will be truncated before written to disk.
406 * Live streams will continue to show the full content.
407 *
408 * @param log
409 * Pass OS_LOG_DEFAULT or a log object previously created with os_log_create.
410 *
411 * @param format
412 * A format string to generate a human-readable log message when the log
413 * line is decoded. This string must be a constant string, not dynamically
414 * generated. Supports all standard printf types and %@ (objects).
415 */
416#define os_log_fault(log, format, ...) __extension__({ \
417 _Static_assert(__builtin_constant_p(format), "format string must be constant"); \
418 __attribute__((section("__TEXT,__os_log"))) static const char _os_log_fmt[] = format; \
419 _os_log_verify_format_str(format, ##__VA_ARGS__); \
420 _os_log_internal(&__dso_handle, log, OS_LOG_TYPE_FAULT, _os_log_fmt, ##__VA_ARGS__); \
421 __asm__(""); /* avoid tailcall */ \
422})
423
424/*!
425 * @function os_log_with_type
426 *
427 * @abstract
428 * Log a message using a specific type.
429 *
430 * @discussion
431 * Will log a message with the provided os_log_type_t.
432 *
433 * @param log
434 * Pass OS_LOG_DEFAULT or a log object previously created with os_log_create.
435 *
436 * @param type
437 * Pass a valid type from os_log_type_t.
438 *
439 * @param format
440 * A format string to generate a human-readable log message when the log
441 * line is decoded. This string must be a constant string, not dynamically
442 * generated. Supports all standard printf types and %@ (objects).
443 */
444#define os_log_with_type(log, type, format, ...) __extension__({ \
445 _Static_assert(__builtin_constant_p(format), "format string must be constant"); \
446 __attribute__((section("__TEXT,__os_log"))) static const char _os_log_fmt[] = format; \
447 _os_log_verify_format_str(format, ##__VA_ARGS__); \
448 _os_log_internal(&__dso_handle, log, type, _os_log_fmt, ##__VA_ARGS__); \
449 __asm__(""); /* avoid tailcall */ \
450})
451
452/*!
453 * @function os_log_sensitive_debug
454 *
455 * @abstract
456 * Insert a debug log message containing sensitive content (i.e., personal
457 * identifying information).
458 *
459 * @discussion
460 * Insert a debug log message containing sensitive content (i.e., personal
461 * identifying information) in accordance with the preferences specified by
462 * the provided log object.
463 *
464 * All strings are considered potentially sensitive, though this call
465 * specifically signifies the message as containing sensitive content.
466 * The message will be stored separately from other messages.
467 *
468 * When an os_activity_id_t is present, the log message will also be scoped by
469 * that identifier. Activities provide granular filtering of log messages
470 * across threads and processes.
471 *
472 * There is a physical cap of 256 bytes per entry for dynamic content,
473 * i.e., %s and %@, that can be written to the persistence store. As such,
474 * all content exceeding the limit will be truncated before written to disk.
475 * Live streams will continue to show the full content.
476 *
477 * @param log
478 * Pass OS_LOG_DEFAULT or a log object previously created with os_log_create.
479 *
480 * @param format
481 * A format string to generate a human-readable log message when the log
482 * line is decoded. This string must be a constant string, not dynamically
483 * generated. Supports all standard printf types and %@ (objects).
484 */
485#define os_log_sensitive_debug(log, format, ...) __extension__({ \
486 _Static_assert(__builtin_constant_p(format), "format string must be constant"); \
487 __attribute__((section("__TEXT,__os_log_sens"))) static const char _os_log_fmt[] = format; \
488 _os_log_verify_format_str(format, ##__VA_ARGS__); \
489 _os_log_sensitive(&__dso_handle, log, OS_LOG_TYPE_DEBUG, _os_log_fmt, ##__VA_ARGS__); \
490 __asm__(""); /* avoid tailcall */ \
491})
492
493#ifdef XNU_KERNEL_PRIVATE
494#define os_log_with_startup_serial(log, format, ...) __extension__({ \
495 if (startup_serial_logging_active) { printf(format, ##__VA_ARGS__); } \
496 else { os_log(log, format, ##__VA_ARGS__); } \
497})
498#endif /* XNU_KERNEL_PRIVATE */
499
500/*!
501 * @function _os_log_internal
502 *
503 * @abstract
504 * Internal function used by macros.
505 */
506__WATCHOS_AVAILABLE(3.0) __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0)
507OS_EXPORT OS_NOTHROW
508void
509_os_log_internal(void *dso, os_log_t log, os_log_type_t type, const char *message, ...);
510
511__END_DECLS
512
513#endif /* __os_log_h */
514