1 // Copyright 2017 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef BASE_FUCHSIA_FUCHSIA_LOGGING_H_
6 #define BASE_FUCHSIA_FUCHSIA_LOGGING_H_
7
8 #include <lib/fidl/cpp/wire/connect_service.h>
9 #include <lib/fidl/cpp/wire/traits.h>
10 #include <lib/fit/function.h>
11 #include <lib/zx/result.h>
12 #include <zircon/types.h>
13
14 #include <string>
15 #include <string_view>
16
17 #include "base/base_export.h"
18 #include "base/check.h"
19 #include "base/logging.h"
20
21 // Use the ZX_LOG family of macros along with a zx_status_t containing a Zircon
22 // error. The error value will be decoded so that logged messages explain the
23 // error.
24
25 namespace logging {
26
27 class BASE_EXPORT ZxLogMessage : public logging::LogMessage {
28 public:
29 ZxLogMessage(const char* file_path,
30 int line,
31 LogSeverity severity,
32 zx_status_t zx_status);
33
34 ZxLogMessage(const ZxLogMessage&) = delete;
35 ZxLogMessage& operator=(const ZxLogMessage&) = delete;
36
37 ~ZxLogMessage() override;
38
39 protected:
40 void AppendError();
41
42 private:
43 zx_status_t zx_status_;
44 };
45
46 class BASE_EXPORT ZxLogMessageFatal final : public ZxLogMessage {
47 public:
48 using ZxLogMessage::ZxLogMessage;
49 [[noreturn]] ~ZxLogMessageFatal() override;
50 };
51
52 } // namespace logging
53
54 #define ZX_LOG_STREAM(severity, zx_status) \
55 COMPACT_GOOGLE_LOG_EX_##severity(ZxLogMessage, zx_status).stream()
56
57 #define ZX_LOG(severity, zx_status) \
58 LAZY_STREAM(ZX_LOG_STREAM(severity, zx_status), LOG_IS_ON(severity))
59 #define ZX_LOG_IF(severity, condition, zx_status) \
60 LAZY_STREAM(ZX_LOG_STREAM(severity, zx_status), \
61 LOG_IS_ON(severity) && (condition))
62
63 #define ZX_CHECK(condition, zx_status) \
64 LAZY_STREAM(ZX_LOG_STREAM(FATAL, zx_status), !(condition)) \
65 << "Check failed: " #condition << ". "
66
67 #define ZX_DLOG(severity, zx_status) \
68 LAZY_STREAM(ZX_LOG_STREAM(severity, zx_status), DLOG_IS_ON(severity))
69
70 #if DCHECK_IS_ON()
71 #define ZX_DLOG_IF(severity, condition, zx_status) \
72 LAZY_STREAM(ZX_LOG_STREAM(severity, zx_status), \
73 DLOG_IS_ON(severity) && (condition))
74 #else // DCHECK_IS_ON()
75 #define ZX_DLOG_IF(severity, condition, zx_status) EAT_STREAM_PARAMETERS
76 #endif // DCHECK_IS_ON()
77
78 #define ZX_DCHECK(condition, zx_status) \
79 LAZY_STREAM(ZX_LOG_STREAM(DFATAL, zx_status), \
80 DCHECK_IS_ON() && !(condition)) \
81 << "Check failed: " #condition << ". "
82
83 namespace base {
84
85 namespace internal {
86
87 BASE_EXPORT std::string FidlMethodResultErrorMessage(
88 std::string_view formatted_error,
89 std::string_view method_name);
90
91 BASE_EXPORT std::string FidlConnectionErrorMessage(
92 std::string_view protocol_name,
93 std::string_view status_string);
94
95 } // namespace internal
96
97 class Location;
98
99 // Returns a function suitable for use as error-handler for a FIDL binding or
100 // helper (e.g. ScenicSession) required by the process to function. Typically
101 // it is unhelpful to simply crash on such failures, so the returned handler
102 // will instead log an ERROR and exit the process.
103 // The Location and protocol name string must be kept valid by the caller, for
104 // as long as the returned fit::function<> remains live.
105 BASE_EXPORT fit::function<void(zx_status_t)> LogFidlErrorAndExitProcess(
106 const Location& from_here,
107 std::string_view protocol_name);
108
109 template <typename Protocol>
FidlConnectionErrorMessage(const zx::result<fidl::ClientEnd<Protocol>> & result)110 BASE_EXPORT std::string FidlConnectionErrorMessage(
111 const zx::result<fidl::ClientEnd<Protocol>>& result) {
112 CHECK(result.is_error());
113 return internal::FidlConnectionErrorMessage(
114 fidl::DiscoverableProtocolName<Protocol>, result.status_string());
115 }
116
117 template <typename FidlMethod>
FidlMethodResultErrorMessage(const fidl::Result<FidlMethod> & result,std::string_view method_name)118 BASE_EXPORT std::string FidlMethodResultErrorMessage(
119 const fidl::Result<FidlMethod>& result,
120 std::string_view method_name) {
121 CHECK(result.is_error());
122 return internal::FidlMethodResultErrorMessage(
123 result.error_value().FormatDescription(), method_name);
124 }
125
126 BASE_EXPORT std::string FidlMethodResultErrorMessage(
127 const fit::result<fidl::OneWayError>& result,
128 std::string_view method_name);
129
130 BASE_EXPORT fit::function<void(fidl::UnbindInfo)>
131 FidlBindingClosureWarningLogger(std::string_view protocol_name);
132
133 template <typename Protocol>
134 BASE_EXPORT fit::function<void(fidl::UnbindInfo)>
FidlBindingClosureWarningLogger()135 FidlBindingClosureWarningLogger() {
136 return FidlBindingClosureWarningLogger(
137 fidl::DiscoverableProtocolName<Protocol>);
138 }
139
140 } // namespace base
141
142 #endif // BASE_FUCHSIA_FUCHSIA_LOGGING_H_
143