diff options
author | tkchin <tkchin@webrtc.org> | 2015-07-23 12:27:02 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-07-23 19:27:06 +0000 |
commit | 28bae02bd383abbd35cc87fa1188a569f1b3c683 (patch) | |
tree | b1584bb2e5e4ecb6d4c3336fdcec2041d025b57b /talk | |
parent | 3ab2f14d56db91665002f36f899c0a97f926d91f (diff) | |
download | webrtc-28bae02bd383abbd35cc87fa1188a569f1b3c683.tar.gz |
Remove CircularFileStream / replace it with CallSessionFileRotatingStream.
BUG=4838, 4839
Review URL: https://codereview.webrtc.org/1245143005
Cr-Commit-Position: refs/heads/master@{#9628}
Diffstat (limited to 'talk')
-rw-r--r-- | talk/app/webrtc/objc/RTCFileLogger.mm | 175 | ||||
-rw-r--r-- | talk/app/webrtc/objc/public/RTCFileLogger.h | 18 |
2 files changed, 59 insertions, 134 deletions
diff --git a/talk/app/webrtc/objc/RTCFileLogger.mm b/talk/app/webrtc/objc/RTCFileLogger.mm index b474d7a5c6..3080ebc080 100644 --- a/talk/app/webrtc/objc/RTCFileLogger.mm +++ b/talk/app/webrtc/objc/RTCFileLogger.mm @@ -28,45 +28,19 @@ #import "RTCFileLogger.h" #include "webrtc/base/checks.h" +#include "webrtc/base/filerotatingstream.h" #include "webrtc/base/logging.h" +#include "webrtc/base/logsinks.h" #include "webrtc/base/scoped_ptr.h" -#include "webrtc/base/stream.h" -NSString *const kDefaultLogFileName = @"webrtc.log"; +NSString *const kDefaultLogDirName = @"webrtc_logs"; NSUInteger const kDefaultMaxFileSize = 10 * 1024 * 1024; // 10MB. -namespace rtc { - -class CircularFileStreamLogSink : public LogSink { - public: - // Creates a log sink that writes to the given stream. This log sink takes - // ownership of |stream|. - CircularFileStreamLogSink(CircularFileStream *stream) { - DCHECK(stream); - _stream.reset(stream); - } - - ~CircularFileStreamLogSink() override {} - - void OnLogMessage(const std::string &message) override { - if (_stream) { - _stream->WriteAll(message.data(), message.size(), nullptr, nullptr); - } - } - - CircularFileStream *GetStream() { return _stream.get(); } - - private: - scoped_ptr<CircularFileStream> _stream; -}; - -} // namespace rtc - @implementation RTCFileLogger { BOOL _hasStarted; - NSString *_filePath; + NSString *_dirPath; NSUInteger _maxFileSize; - rtc::scoped_ptr<rtc::CircularFileStreamLogSink> _logSink; + rtc::scoped_ptr<rtc::CallSessionFileRotatingLogSink> _logSink; } @synthesize severity = _severity; @@ -75,18 +49,34 @@ class CircularFileStreamLogSink : public LogSink { NSArray *paths = NSSearchPathForDirectoriesInDomains( NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirPath = [paths firstObject]; - NSString *defaultFilePath = - [documentsDirPath stringByAppendingPathComponent:kDefaultLogFileName]; - return [self initWithFilePath:defaultFilePath - maxFileSize:kDefaultMaxFileSize]; + NSString *defaultDirPath = + [documentsDirPath stringByAppendingPathComponent:kDefaultLogDirName]; + return [self initWithDirPath:defaultDirPath + maxFileSize:kDefaultMaxFileSize]; } -- (instancetype)initWithFilePath:(NSString *)filePath - maxFileSize:(NSUInteger)maxFileSize { - NSParameterAssert(filePath.length); +- (instancetype)initWithDirPath:(NSString *)dirPath + maxFileSize:(NSUInteger)maxFileSize { + NSParameterAssert(dirPath.length); NSParameterAssert(maxFileSize); if (self = [super init]) { - _filePath = filePath; + BOOL isDir = NO; + NSFileManager *fileManager = [NSFileManager defaultManager]; + if ([fileManager fileExistsAtPath:dirPath isDirectory:&isDir]) { + if (!isDir) { + // Bail if something already exists there. + return nil; + } + } else { + if (![fileManager createDirectoryAtPath:dirPath + withIntermediateDirectories:NO + attributes:nil + error:nil]) { + // Bail if we failed to create a directory. + return nil; + } + } + _dirPath = dirPath; _maxFileSize = maxFileSize; _severity = kRTCFileLoggerSeverityInfo; } @@ -101,19 +91,14 @@ class CircularFileStreamLogSink : public LogSink { if (_hasStarted) { return; } - rtc::scoped_ptr<rtc::CircularFileStream> stream; - stream.reset(new rtc::CircularFileStream(_maxFileSize)); - _logSink.reset(new rtc::CircularFileStreamLogSink(stream.release())); - int error = 0; - if (!_logSink->GetStream()->Open(_filePath.UTF8String, "wb", &error)) { - LOG(LS_ERROR) << "Failed to open log file at path: " - << _filePath.UTF8String - << " Error: " - << error; + _logSink.reset(new rtc::CallSessionFileRotatingLogSink(_dirPath.UTF8String, + _maxFileSize)); + if (!_logSink->Init()) { + LOG(LS_ERROR) << "Failed to open log files at path: " + << _dirPath.UTF8String; _logSink.reset(); return; } - // TODO(tkchin): Log thead info on iOS, currently this doesn't do anything. rtc::LogMessage::LogThreads(true); rtc::LogMessage::LogTimestamps(true); rtc::LogMessage::AddLogToStream(_logSink.get(), [self rtcSeverity]); @@ -127,93 +112,35 @@ class CircularFileStreamLogSink : public LogSink { DCHECK(_logSink); rtc::LogMessage::RemoveLogToStream(_logSink.get()); _hasStarted = NO; - - // Read the ordered version of the log. - NSData *logData = [self reorderedLogData]; - NSError *error = nil; - // Write the ordered version back to disk. - if (![logData writeToFile:_filePath - options:NSDataWritingAtomic - error:&error]) { - LOG(LS_ERROR) << "Failed to rewrite log to disk at path: " - << _filePath.UTF8String; - if (error) { - LOG(LS_ERROR) << "Error: " << error.localizedDescription.UTF8String; - } - } else { - // If we succeeded in writing to disk we don't need to hold on to the - // stream anymore. - _logSink.reset(); - } + _logSink.reset(); } - (NSData *)logData { if (_hasStarted) { return nil; } - if (!_logSink.get()) { - // If there isn't a previously used stream just return contents of file. - return [[self class] contentsOfFileAtPath:_filePath]; + NSMutableData* logData = [NSMutableData data]; + rtc::scoped_ptr<rtc::CallSessionFileRotatingStream> stream( + new rtc::CallSessionFileRotatingStream(_dirPath.UTF8String)); + if (!stream->Open()) { + return logData; } - return [self reorderedLogData]; -} - -#pragma mark - Private - -+ (NSData *)contentsOfFileAtPath:(NSString *)path { - NSError *error = nil; - NSData *contents = [NSData dataWithContentsOfFile:path - options:0 - error:&error]; - if (error) { - LOG(LS_ERROR) << "Failed to read contents of file at path: " - << path.UTF8String - << " Error: " - << error.localizedDescription.UTF8String; - return nil; - } - return contents; -} - -- (NSData *)reorderedLogData { - if (_hasStarted || !_logSink.get()) { - return nil; - } - // We have a stream we used for writing in memory and we're not writing. The - // stream has a pointer to where the log boundary is so it can reorder the - // log correctly. We just need to reopen the file in read mode. - int error = 0; - rtc::CircularFileStream *stream = _logSink->GetStream(); - if (!stream->Open(_filePath.UTF8String, "r", &error)) { - LOG(LS_ERROR) << "Failed to open log file at path: " - << _filePath.UTF8String - << " Error: " - << error; - return nil; - } - size_t logSize = 0; - size_t bytesRead = 0; - error = 0; - if (!stream->GetSize(&logSize)) { - LOG(LS_ERROR) << "Failed to get log file size."; - return nil; + size_t bufferSize = 0; + if (!stream->GetSize(&bufferSize) || bufferSize == 0) { + return logData; } + size_t read = 0; // Allocate memory using malloc so we can pass it direcly to NSData without // copying. - rtc::scoped_ptr<uint8_t[]> buffer(static_cast<uint8_t*>(malloc(logSize))); - if (stream->ReadAll(buffer.get(), logSize, &bytesRead, &error) - != rtc::SR_SUCCESS) { - LOG(LS_ERROR) << "Failed to read log file at path: " - << _filePath.UTF8String - << " Error: " - << error; - } - DCHECK_LE(bytesRead, logSize); - // NSData takes ownership of the bytes and frees it on dealloc. - return [NSData dataWithBytesNoCopy:buffer.release() - length:bytesRead]; + rtc::scoped_ptr<uint8_t[]> buffer(static_cast<uint8_t*>(malloc(bufferSize))); + stream->ReadAll(buffer.get(), bufferSize, &read, nullptr); + logData = [[NSMutableData alloc] initWithBytesNoCopy:buffer.release() + length:read]; + return logData; } +#pragma mark - Private + - (rtc::LoggingSeverity)rtcSeverity { switch (_severity) { case kRTCFileLoggerSeverityVerbose: diff --git a/talk/app/webrtc/objc/public/RTCFileLogger.h b/talk/app/webrtc/objc/public/RTCFileLogger.h index 5c311b711a..3900cb6fbe 100644 --- a/talk/app/webrtc/objc/public/RTCFileLogger.h +++ b/talk/app/webrtc/objc/public/RTCFileLogger.h @@ -49,24 +49,22 @@ typedef NS_ENUM(NSUInteger, RTCFileLoggerSeverity) { // The severity level to capture. The default is kRTCFileLoggerSeverityInfo. @property(nonatomic, assign) RTCFileLoggerSeverity severity; -// Default constructor provides default settings for file path and file size. +// Default constructor provides default settings for dir path and file size. - (instancetype)init; -- (instancetype)initWithFilePath:(NSString *)filePath - maxFileSize:(NSUInteger)maxFileSize +- (instancetype)initWithDirPath:(NSString *)dirPath + maxFileSize:(NSUInteger)maxFileSize NS_DESIGNATED_INITIALIZER; -// Starts writing WebRTC logs to file if not already started. Overwrites any -// existing file. +// Starts writing WebRTC logs to disk if not already started. Overwrites any +// existing file(s). - (void)start; -// Stops writing WebRTC logs to file. Rewrites the log file as required to -// reorder logs because logs may be disordered due to use of -// rtc::CircularFileStream. This method is also called on dealloc. +// Stops writing WebRTC logs to disk. This method is also called on dealloc. - (void)stop; -// Returns the current contents of the log file. Returns nil if start has been -// called without a stop, or if there is no data. +// Returns the current contents of the logs, or nil if start has been called +// without a stop. - (NSData *)logData; @end |