Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(19)

Side by Side Diff: talk/app/webrtc/objc/RTCFileLogger.mm

Issue 1217473011: AppRTCDemo file logging. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc@master
Patch Set: Rebase Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | talk/app/webrtc/objc/public/RTCFileLogger.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * libjingle
3 * Copyright 2015 Google Inc.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 #import "RTCFileLogger.h"
29
30 #include "webrtc/base/checks.h"
31 #include "webrtc/base/logging.h"
32 #include "webrtc/base/scoped_ptr.h"
33 #include "webrtc/base/stream.h"
34
35 NSString *const kDefaultLogFileName = @"webrtc.log";
36 NSUInteger const kDefaultMaxFileSize = 10 * 1024 * 1024; // 10MB.
37
38 namespace rtc {
39
40 class CircularFileStreamLogSink : public LogSink {
41 public:
42 // Creates a log sink that writes to the given stream. This log sink takes
43 // ownership of |stream|.
44 CircularFileStreamLogSink(CircularFileStream *stream) {
45 DCHECK(stream);
46 _stream.reset(stream);
47 }
48
49 ~CircularFileStreamLogSink() override {}
50
51 void OnLogMessage(const std::string &message) override {
52 if (_stream) {
53 _stream->WriteAll(message.data(), message.size(), nullptr, nullptr);
54 }
55 }
56
57 CircularFileStream *GetStream() { return _stream.get(); }
58
59 private:
60 scoped_ptr<CircularFileStream> _stream;
61 };
62
63 } // namespace rtc
64
65 @implementation RTCFileLogger {
66 BOOL _hasStarted;
67 NSString *_filePath;
68 NSUInteger _maxFileSize;
69 rtc::scoped_ptr<rtc::CircularFileStreamLogSink> _logSink;
70 }
71
72 @synthesize severity = _severity;
73
74 - (instancetype)init {
75 NSArray *paths = NSSearchPathForDirectoriesInDomains(
76 NSDocumentDirectory, NSUserDomainMask, YES);
77 NSString *documentsDirPath = [paths firstObject];
78 NSString *defaultFilePath =
79 [documentsDirPath stringByAppendingPathComponent:kDefaultLogFileName];
80 return [self initWithFilePath:defaultFilePath
81 maxFileSize:kDefaultMaxFileSize];
82 }
83
84 - (instancetype)initWithFilePath:(NSString *)filePath
85 maxFileSize:(NSUInteger)maxFileSize {
86 NSParameterAssert(filePath.length);
87 NSParameterAssert(maxFileSize);
88 if (self = [super init]) {
89 _filePath = filePath;
90 _maxFileSize = maxFileSize;
91 _severity = kRTCFileLoggerSeverityInfo;
92 }
93 return self;
94 }
95
96 - (void)dealloc {
97 [self stop];
98 }
99
100 - (void)start {
101 if (_hasStarted) {
102 return;
103 }
104 rtc::scoped_ptr<rtc::CircularFileStream> stream;
105 stream.reset(new rtc::CircularFileStream(_maxFileSize));
106 _logSink.reset(new rtc::CircularFileStreamLogSink(stream.release()));
107 int error = 0;
108 if (!_logSink->GetStream()->Open(_filePath.UTF8String, "wb", &error)) {
109 LOG(LS_ERROR) << "Failed to open log file at path: "
110 << _filePath.UTF8String
111 << " Error: "
112 << error;
113 _logSink.reset();
114 return;
115 }
116 // TODO(tkchin): Log thead info on iOS, currently this doesn't do anything.
henrika_webrtc 2015/07/15 08:36:01 It actually does now :-) Please try it out.
117 rtc::LogMessage::LogThreads(true);
118 rtc::LogMessage::LogTimestamps(true);
119 rtc::LogMessage::AddLogToStream(_logSink.get(), [self rtcSeverity]);
120 _hasStarted = YES;
121 }
122
123 - (void)stop {
124 if (!_hasStarted) {
125 return;
126 }
127 DCHECK(_logSink);
128 rtc::LogMessage::RemoveLogToStream(_logSink.get());
129 _hasStarted = NO;
130
131 // Read the ordered version of the log.
132 NSData *logData = [self reorderedLogData];
133 NSError *error = nil;
134 // Write the ordered version back to disk.
135 if (![logData writeToFile:_filePath
136 options:NSDataWritingAtomic
137 error:&error]) {
138 LOG(LS_ERROR) << "Failed to rewrite log to disk at path: "
139 << _filePath.UTF8String;
140 if (error) {
141 LOG(LS_ERROR) << "Error: " << error.localizedDescription.UTF8String;
142 }
143 } else {
144 // If we succeeded in writing to disk we don't need to hold on to the
145 // stream anymore.
146 _logSink.reset();
147 }
148 }
149
150 - (NSData *)logData {
151 if (_hasStarted) {
152 return nil;
153 }
154 if (!_logSink.get()) {
155 // If there isn't a previously used stream just return contents of file.
156 return [[self class] contentsOfFileAtPath:_filePath];
157 }
158 return [self reorderedLogData];
159 }
160
161 #pragma mark - Private
162
163 + (NSData *)contentsOfFileAtPath:(NSString *)path {
164 NSError *error = nil;
165 NSData *contents = [NSData dataWithContentsOfFile:path
166 options:0
167 error:&error];
168 if (error) {
169 LOG(LS_ERROR) << "Failed to read contents of file at path: "
170 << path.UTF8String
171 << " Error: "
172 << error.localizedDescription.UTF8String;
173 return nil;
174 }
175 return contents;
176 }
177
178 - (NSData *)reorderedLogData {
179 if (_hasStarted || !_logSink.get()) {
180 return nil;
181 }
182 // We have a stream we used for writing in memory and we're not writing. The
183 // stream has a pointer to where the log boundary is so it can reorder the
184 // log correctly. We just need to reopen the file in read mode.
185 int error = 0;
186 rtc::CircularFileStream *stream = _logSink->GetStream();
187 if (!stream->Open(_filePath.UTF8String, "r", &error)) {
188 LOG(LS_ERROR) << "Failed to open log file at path: "
189 << _filePath.UTF8String
190 << " Error: "
191 << error;
192 return nil;
193 }
194 size_t logSize = 0;
195 size_t bytesRead = 0;
196 error = 0;
197 if (!stream->GetSize(&logSize)) {
198 LOG(LS_ERROR) << "Failed to get log file size.";
199 return nil;
200 }
201 // Allocate memory using malloc so we can pass it direcly to NSData without
202 // copying.
203 rtc::scoped_ptr<uint8_t[]> buffer(static_cast<uint8_t*>(malloc(logSize)));
204 if (stream->ReadAll(buffer.get(), logSize, &bytesRead, &error)
205 != rtc::SR_SUCCESS) {
206 LOG(LS_ERROR) << "Failed to read log file at path: "
207 << _filePath.UTF8String
208 << " Error: "
209 << error;
210 }
211 DCHECK_LE(bytesRead, logSize);
212 // NSData takes ownership of the bytes and frees it on dealloc.
213 return [NSData dataWithBytesNoCopy:buffer.release()
214 length:bytesRead];
215 }
216
217 - (rtc::LoggingSeverity)rtcSeverity {
218 switch (_severity) {
219 case kRTCFileLoggerSeverityVerbose:
220 return rtc::LS_VERBOSE;
221 case kRTCFileLoggerSeverityInfo:
222 return rtc::LS_INFO;
223 case kRTCFileLoggerSeverityWarning:
224 return rtc::LS_WARNING;
225 case kRTCFileLoggerSeverityError:
226 return rtc::LS_ERROR;
227 }
228 }
229
230 @end
OLDNEW
« no previous file with comments | « no previous file | talk/app/webrtc/objc/public/RTCFileLogger.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698