Add severity into RTC logging callbacks

Bug: webrtc:9945
Change-Id: I5022f63103503d2213492d3cd1a6953fe658fda7
Reviewed-on: https://webrtc-review.googlesource.com/c/108981
Commit-Queue: Jiawei Ou <ouj@fb.com>
Reviewed-by: Anders Carlsson <andersc@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#25510}
This commit is contained in:
Jiawei Ou 2018-10-31 23:14:24 -07:00 committed by Commit Bot
parent edfb883c85
commit 3ea187803b
7 changed files with 195 additions and 15 deletions

View File

@ -73,7 +73,12 @@ CriticalSection g_log_crit;
void LogSink::OnLogMessage(const std::string& msg, void LogSink::OnLogMessage(const std::string& msg,
LoggingSeverity severity, LoggingSeverity severity,
const char* tag) { const char* tag) {
OnLogMessage(tag + (": " + msg)); OnLogMessage(tag + (": " + msg), severity);
}
void LogSink::OnLogMessage(const std::string& msg,
LoggingSeverity /* severity */) {
OnLogMessage(msg);
} }
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
@ -206,7 +211,7 @@ LogMessage::~LogMessage() {
#if defined(WEBRTC_ANDROID) #if defined(WEBRTC_ANDROID)
kv.first->OnLogMessage(str, severity_, tag_); kv.first->OnLogMessage(str, severity_, tag_);
#else #else
kv.first->OnLogMessage(str); kv.first->OnLogMessage(str, severity_);
#endif #endif
} }
} }

View File

@ -115,6 +115,8 @@ class LogSink {
virtual void OnLogMessage(const std::string& msg, virtual void OnLogMessage(const std::string& msg,
LoggingSeverity severity, LoggingSeverity severity,
const char* tag); const char* tag);
virtual void OnLogMessage(const std::string& message,
LoggingSeverity severity);
virtual void OnLogMessage(const std::string& message) = 0; virtual void OnLogMessage(const std::string& message) = 0;
}; };

View File

@ -15,6 +15,10 @@
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
typedef void (^RTCCallbackLoggerMessageHandler)(NSString *message);
typedef void (^RTCCallbackLoggerMessageAndSeverityHandler)(NSString *message,
RTCLoggingSeverity severity);
// This class intercepts WebRTC logs and forwards them to a registered block. // This class intercepts WebRTC logs and forwards them to a registered block.
// This class is not threadsafe. // This class is not threadsafe.
RTC_OBJC_EXPORT RTC_OBJC_EXPORT
@ -23,10 +27,12 @@ RTC_OBJC_EXPORT
// The severity level to capture. The default is kRTCLoggingSeverityInfo. // The severity level to capture. The default is kRTCLoggingSeverityInfo.
@property(nonatomic, assign) RTCLoggingSeverity severity; @property(nonatomic, assign) RTCLoggingSeverity severity;
// The callback will be called on the same thread that does the logging, so // The callback handler will be called on the same thread that does the
// if the logging callback can be slow it may be a good idea to implement // logging, so if the logging callback can be slow it may be a good idea
// dispatching to some other queue. // to implement dispatching to some other queue.
- (void)start:(nullable void (^)(NSString*))callback; - (void)start:(nullable RTCCallbackLoggerMessageHandler)handler;
- (void)startWithMessageAndSeverityHandler:
(nullable RTCCallbackLoggerMessageAndSeverityHandler)handler;
- (void)stop; - (void)stop;

View File

@ -18,11 +18,8 @@
class CallbackLogSink : public rtc::LogSink { class CallbackLogSink : public rtc::LogSink {
public: public:
CallbackLogSink(void (^callbackHandler)(NSString *message)) { CallbackLogSink(RTCCallbackLoggerMessageHandler callbackHandler)
callback_handler_ = callbackHandler; : callback_handler_(callbackHandler) {}
}
~CallbackLogSink() override { callback_handler_ = nil; }
void OnLogMessage(const std::string &message) override { void OnLogMessage(const std::string &message) override {
if (callback_handler_) { if (callback_handler_) {
@ -31,12 +28,47 @@ class CallbackLogSink : public rtc::LogSink {
} }
private: private:
void (^callback_handler_)(NSString *message); RTCCallbackLoggerMessageHandler callback_handler_;
};
class CallbackWithSeverityLogSink : public rtc::LogSink {
public:
CallbackWithSeverityLogSink(RTCCallbackLoggerMessageAndSeverityHandler callbackHandler)
: callback_handler_(callbackHandler) {}
void OnLogMessage(const std::string& message) override { RTC_NOTREACHED(); }
void OnLogMessage(const std::string& message, rtc::LoggingSeverity severity) override {
if (callback_handler_) {
RTCLoggingSeverity loggingSeverity = NativeSeverityToObjcSeverity(severity);
callback_handler_([NSString stringWithUTF8String:message.c_str()], loggingSeverity);
}
}
private:
static RTCLoggingSeverity NativeSeverityToObjcSeverity(rtc::LoggingSeverity severity) {
switch (severity) {
case rtc::LS_SENSITIVE:
return RTCLoggingSeveritySensitive;
case rtc::LS_VERBOSE:
return RTCLoggingSeverityVerbose;
case rtc::LS_INFO:
return RTCLoggingSeverityInfo;
case rtc::LS_WARNING:
return RTCLoggingSeverityWarning;
case rtc::LS_ERROR:
return RTCLoggingSeverityError;
case rtc::LS_NONE:
return RTCLoggingSeverityNone;
}
}
RTCCallbackLoggerMessageAndSeverityHandler callback_handler_;
}; };
@implementation RTCCallbackLogger { @implementation RTCCallbackLogger {
BOOL _hasStarted; BOOL _hasStarted;
std::unique_ptr<CallbackLogSink> _logSink; std::unique_ptr<rtc::LogSink> _logSink;
} }
@synthesize severity = _severity; @synthesize severity = _severity;
@ -53,12 +85,24 @@ class CallbackLogSink : public rtc::LogSink {
[self stop]; [self stop];
} }
- (void)start:(nullable void (^)(NSString *))callback { - (void)start:(nullable RTCCallbackLoggerMessageHandler)handler {
if (_hasStarted) { if (_hasStarted) {
return; return;
} }
_logSink.reset(new CallbackLogSink(callback)); _logSink.reset(new CallbackLogSink(handler));
rtc::LogMessage::AddLogToStream(_logSink.get(), [self rtcSeverity]);
_hasStarted = YES;
}
- (void)startWithMessageAndSeverityHandler:
(nullable RTCCallbackLoggerMessageAndSeverityHandler)handler {
if (_hasStarted) {
return;
}
_logSink.reset(new CallbackWithSeverityLogSink(handler));
rtc::LogMessage::AddLogToStream(_logSink.get(), [self rtcSeverity]); rtc::LogMessage::AddLogToStream(_logSink.get(), [self rtcSeverity]);
_hasStarted = YES; _hasStarted = YES;
@ -78,6 +122,8 @@ class CallbackLogSink : public rtc::LogSink {
- (rtc::LoggingSeverity)rtcSeverity { - (rtc::LoggingSeverity)rtcSeverity {
switch (_severity) { switch (_severity) {
case RTCLoggingSeveritySensitive:
return rtc::LS_SENSITIVE;
case RTCLoggingSeverityVerbose: case RTCLoggingSeverityVerbose:
return rtc::LS_VERBOSE; return rtc::LS_VERBOSE;
case RTCLoggingSeverityInfo: case RTCLoggingSeverityInfo:

View File

@ -14,6 +14,7 @@
// Subset of rtc::LoggingSeverity. // Subset of rtc::LoggingSeverity.
typedef NS_ENUM(NSInteger, RTCLoggingSeverity) { typedef NS_ENUM(NSInteger, RTCLoggingSeverity) {
RTCLoggingSeveritySensitive,
RTCLoggingSeverityVerbose, RTCLoggingSeverityVerbose,
RTCLoggingSeverityInfo, RTCLoggingSeverityInfo,
RTCLoggingSeverityWarning, RTCLoggingSeverityWarning,

View File

@ -14,6 +14,8 @@
rtc::LoggingSeverity RTCGetNativeLoggingSeverity(RTCLoggingSeverity severity) { rtc::LoggingSeverity RTCGetNativeLoggingSeverity(RTCLoggingSeverity severity) {
switch (severity) { switch (severity) {
case RTCLoggingSeveritySensitive:
return rtc::LS_SENSITIVE;
case RTCLoggingSeverityVerbose: case RTCLoggingSeverityVerbose:
return rtc::LS_VERBOSE; return rtc::LS_VERBOSE;
case RTCLoggingSeverityInfo: case RTCLoggingSeverityInfo:

View File

@ -49,6 +49,23 @@
[self waitForExpectations:@[ callbackExpectation ] timeout:10.0]; [self waitForExpectations:@[ callbackExpectation ] timeout:10.0];
} }
- (void)testCallbackWithSeverityGetsCalledForAppropriateLevel {
self.logger.severity = RTCLoggingSeverityWarning;
XCTestExpectation *callbackExpectation = [self expectationWithDescription:@"callbackWarning"];
[self.logger
startWithMessageAndSeverityHandler:^(NSString *message, RTCLoggingSeverity severity) {
XCTAssertTrue([message hasSuffix:@"Horrible error\n"]);
XCTAssertEqual(severity, RTCLoggingSeverityError);
[callbackExpectation fulfill];
}];
RTCLogError("Horrible error");
[self waitForExpectations:@[ callbackExpectation ] timeout:10.0];
}
- (void)testCallbackDoesNotGetCalledForOtherLevels { - (void)testCallbackDoesNotGetCalledForOtherLevels {
self.logger.severity = RTCLoggingSeverityError; self.logger.severity = RTCLoggingSeverityError;
@ -66,6 +83,25 @@
[self waitForExpectations:@[ callbackExpectation ] timeout:10.0]; [self waitForExpectations:@[ callbackExpectation ] timeout:10.0];
} }
- (void)testCallbackWithSeverityDoesNotGetCalledForOtherLevels {
self.logger.severity = RTCLoggingSeverityError;
XCTestExpectation *callbackExpectation = [self expectationWithDescription:@"callbackError"];
[self.logger
startWithMessageAndSeverityHandler:^(NSString *message, RTCLoggingSeverity severity) {
XCTAssertTrue([message hasSuffix:@"Horrible error\n"]);
XCTAssertEqual(severity, RTCLoggingSeverityError);
[callbackExpectation fulfill];
}];
RTCLogInfo("Just some info");
RTCLogWarning("Warning warning");
RTCLogError("Horrible error");
[self waitForExpectations:@[ callbackExpectation ] timeout:10.0];
}
- (void)testCallbackDoesNotgetCalledForSeverityNone { - (void)testCallbackDoesNotgetCalledForSeverityNone {
self.logger.severity = RTCLoggingSeverityNone; self.logger.severity = RTCLoggingSeverityNone;
@ -85,12 +121,38 @@
XCTAssertEqual(result, XCTWaiterResultTimedOut); XCTAssertEqual(result, XCTWaiterResultTimedOut);
} }
- (void)testCallbackWithSeverityDoesNotgetCalledForSeverityNone {
self.logger.severity = RTCLoggingSeverityNone;
XCTestExpectation *callbackExpectation = [self expectationWithDescription:@"unexpectedCallback"];
[self.logger
startWithMessageAndSeverityHandler:^(NSString *message, RTCLoggingSeverity severity) {
[callbackExpectation fulfill];
XCTAssertTrue(false);
}];
RTCLogInfo("Just some info");
RTCLogWarning("Warning warning");
RTCLogError("Horrible error");
XCTWaiter *waiter = [[XCTWaiter alloc] init];
XCTWaiterResult result = [waiter waitForExpectations:@[ callbackExpectation ] timeout:1.0];
XCTAssertEqual(result, XCTWaiterResultTimedOut);
}
- (void)testStartingWithNilCallbackDoesNotCrash { - (void)testStartingWithNilCallbackDoesNotCrash {
[self.logger start:nil]; [self.logger start:nil];
RTCLogError("Horrible error"); RTCLogError("Horrible error");
} }
- (void)testStartingWithNilCallbackWithSeverityDoesNotCrash {
[self.logger startWithMessageAndSeverityHandler:nil];
RTCLogError("Horrible error");
}
- (void)testStopCallbackLogger { - (void)testStopCallbackLogger {
XCTestExpectation *callbackExpectation = [self expectationWithDescription:@"stopped"]; XCTestExpectation *callbackExpectation = [self expectationWithDescription:@"stopped"];
@ -107,6 +169,23 @@
XCTAssertEqual(result, XCTWaiterResultTimedOut); XCTAssertEqual(result, XCTWaiterResultTimedOut);
} }
- (void)testStopCallbackWithSeverityLogger {
XCTestExpectation *callbackExpectation = [self expectationWithDescription:@"stopped"];
[self.logger
startWithMessageAndSeverityHandler:^(NSString *message, RTCLoggingSeverity loggingServerity) {
[callbackExpectation fulfill];
}];
[self.logger stop];
RTCLogInfo("Just some info");
XCTWaiter *waiter = [[XCTWaiter alloc] init];
XCTWaiterResult result = [waiter waitForExpectations:@[ callbackExpectation ] timeout:1.0];
XCTAssertEqual(result, XCTWaiterResultTimedOut);
}
- (void)testDestroyingCallbackLogger { - (void)testDestroyingCallbackLogger {
XCTestExpectation *callbackExpectation = [self expectationWithDescription:@"destroyed"]; XCTestExpectation *callbackExpectation = [self expectationWithDescription:@"destroyed"];
@ -123,4 +202,43 @@
XCTAssertEqual(result, XCTWaiterResultTimedOut); XCTAssertEqual(result, XCTWaiterResultTimedOut);
} }
- (void)testDestroyingCallbackWithSeverityLogger {
XCTestExpectation *callbackExpectation = [self expectationWithDescription:@"destroyed"];
[self.logger
startWithMessageAndSeverityHandler:^(NSString *message, RTCLoggingSeverity loggingServerity) {
[callbackExpectation fulfill];
}];
self.logger = nil;
RTCLogInfo("Just some info");
XCTWaiter *waiter = [[XCTWaiter alloc] init];
XCTWaiterResult result = [waiter waitForExpectations:@[ callbackExpectation ] timeout:1.0];
XCTAssertEqual(result, XCTWaiterResultTimedOut);
}
- (void)testCallbackWithSeverityLoggerCannotStartTwice {
self.logger.severity = RTCLoggingSeverityWarning;
XCTestExpectation *callbackExpectation = [self expectationWithDescription:@"callbackWarning"];
[self.logger
startWithMessageAndSeverityHandler:^(NSString *message, RTCLoggingSeverity loggingServerity) {
XCTAssertTrue([message hasSuffix:@"Horrible error\n"]);
XCTAssertEqual(loggingServerity, RTCLoggingSeverityError);
[callbackExpectation fulfill];
}];
[self.logger start:^(NSString *message) {
[callbackExpectation fulfill];
XCTAssertTrue(false);
}];
RTCLogError("Horrible error");
[self waitForExpectations:@[ callbackExpectation ] timeout:10.0];
}
@end @end