OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 | 5 |
6 /** @suppress {duplicate} */ | 6 /** @suppress {duplicate} */ |
7 var remoting = remoting || {}; | 7 var remoting = remoting || {}; |
8 | 8 |
9 (function() { | 9 (function() { |
10 | 10 |
11 'use strict'; | 11 'use strict'; |
12 | 12 |
13 /** | 13 /** |
14 * |remoting.SessionLogger| is responsible for reporting telemetry entries for | 14 * |remoting.SessionLogger| is responsible for reporting telemetry entries for |
15 * a Chromoting session. | 15 * a Chromoting session. |
16 * | 16 * |
17 * @param {remoting.ChromotingEvent.Role} role | 17 * @param {remoting.ChromotingEvent.Role} role |
18 * @param {function(!Object)} writeLogEntry | 18 * @param {function(!Object)} writeLogEntry |
19 * | 19 * |
20 * @constructor | 20 * @constructor |
21 */ | 21 */ |
22 remoting.SessionLogger = function(role, writeLogEntry) { | 22 remoting.SessionLogger = function(role, writeLogEntry) { |
23 /** @private */ | 23 /** @private */ |
24 this.role_ = role; | 24 this.role_ = role; |
25 /** @private */ | 25 /** @private */ |
26 this.writeLogEntry_ = writeLogEntry; | 26 this.writeLogEntry_ = writeLogEntry; |
27 /** @private */ | 27 /** @private */ |
28 this.statsAccumulator_ = new remoting.StatsAccumulator(); | |
29 /** @private */ | |
30 this.sessionId_ = ''; | 28 this.sessionId_ = ''; |
31 /** @private */ | 29 /** @private */ |
32 this.sessionIdGenerationTime_ = 0; | 30 this.sessionIdGenerationTime_ = 0; |
33 /** @private */ | 31 /** @private */ |
34 this.sessionStartTime_ = Date.now(); | 32 this.sessionStartTime_ = Date.now(); |
35 /** @private */ | 33 /** @private */ |
36 this.sessionEndTime_ = 0; | 34 this.sessionEndTime_ = 0; |
37 /** @private {remoting.ChromotingEvent.ConnectionType} */ | 35 /** @private {remoting.ChromotingEvent.ConnectionType} */ |
38 this.connectionType_; | 36 this.connectionType_; |
39 /** @private {remoting.ChromotingEvent.SessionEntryPoint} */ | 37 /** @private {remoting.ChromotingEvent.SessionEntryPoint} */ |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
228 this.log_(entry); | 226 this.log_(entry); |
229 | 227 |
230 this.lastSessionEntry_ = | 228 this.lastSessionEntry_ = |
231 /** @type {remoting.ChromotingEvent} */ (base.deepCopy(entry)); | 229 /** @type {remoting.ChromotingEvent} */ (base.deepCopy(entry)); |
232 | 230 |
233 // Update the session summary. | 231 // Update the session summary. |
234 if (remoting.ChromotingEvent.isEndOfSession(entry)) { | 232 if (remoting.ChromotingEvent.isEndOfSession(entry)) { |
235 this.sessionEndTime_ = Date.now(); | 233 this.sessionEndTime_ = Date.now(); |
236 } | 234 } |
237 | 235 |
238 // Don't accumulate connection statistics across state changes. | 236 if (state == remoting.ChromotingEvent.SessionState.CLOSED || |
239 this.logAccumulatedStatistics_(); | |
240 this.statsAccumulator_.empty(); | |
241 | |
242 if (state == remoting.ChromotingEvent.SessionState.CLOSED || | |
243 state == remoting.ChromotingEvent.SessionState.CONNECTION_DROPPED) { | 237 state == remoting.ChromotingEvent.SessionState.CONNECTION_DROPPED) { |
244 this.flushFeatureTracker(); | 238 this.flushFeatureTracker(); |
245 } | 239 } |
246 }; | 240 }; |
247 | 241 |
248 /** | 242 /** |
249 * Logs connection statistics. | 243 * Logs connection statistics. |
250 * | 244 * |
251 * @param {Object<number>} stats The connection statistics | 245 * @param {remoting.ClientSession.PerfStats} stats The connection statistics |
252 */ | 246 */ |
253 remoting.SessionLogger.prototype.logStatistics = function(stats) { | 247 remoting.SessionLogger.prototype.logStatistics = function(stats) { |
254 this.maybeExpireSessionId_(); | 248 if (stats && remoting.ClientSession.PerfStats.hasValidField(stats)) { |
255 // Store the statistics. | 249 this.maybeExpireSessionId_(); |
256 this.statsAccumulator_.add(stats); | 250 var entry = this.makeStats_(stats); |
257 // Send statistics to the server if they've been accumulating for at least | 251 this.log_(entry); |
258 // 60 seconds. | |
259 if (this.statsAccumulator_.getTimeSinceFirstValue() >= | |
260 remoting.SessionLogger.CONNECTION_STATS_ACCUMULATE_TIME) { | |
261 this.logAccumulatedStatistics_(); | |
262 } | 252 } |
263 }; | 253 }; |
264 | 254 |
265 /** | 255 /** |
266 * Logs host and client dimensions. | 256 * Logs host and client dimensions. |
267 * | 257 * |
268 * @param {{width: number, height: number}} hostSize | 258 * @param {{width: number, height: number}} hostSize |
| 259 * @param {number} hostDpi |
269 * @param {{width: number, height: number}} clientPluginSize | 260 * @param {{width: number, height: number}} clientPluginSize |
| 261 * @param {number} clientDpi |
270 * @param {{width: number, height: number}} clientWindowSize | 262 * @param {{width: number, height: number}} clientWindowSize |
271 * @param {boolean} clientFullscreen | 263 * @param {boolean} clientFullscreen |
272 */ | 264 */ |
273 remoting.SessionLogger.prototype.logScreenResolutions = | 265 remoting.SessionLogger.prototype.logScreenResolutions = |
274 function(hostSize, hostDpi, clientPluginSize, clientWindowSize, clientDpi, | 266 function(hostSize, hostDpi, clientPluginSize, clientWindowSize, clientDpi, |
275 clientFullscreen) { | 267 clientFullscreen) { |
276 this.maybeExpireSessionId_(); | 268 this.maybeExpireSessionId_(); |
277 var entry = this.makeScreenResolutions_(hostSize, hostDpi, clientPluginSize, | 269 var entry = this.makeScreenResolutions_(hostSize, hostDpi, clientPluginSize, |
278 clientWindowSize, clientDpi, | 270 clientWindowSize, clientDpi, |
279 clientFullscreen); | 271 clientFullscreen); |
(...skipping 22 matching lines...) Expand all Loading... |
302 } | 294 } |
303 | 295 |
304 entry.session_state = state; | 296 entry.session_state = state; |
305 | 297 |
306 this.fillEvent_(entry); | 298 this.fillEvent_(entry); |
307 return entry; | 299 return entry; |
308 }; | 300 }; |
309 | 301 |
310 /** | 302 /** |
311 * @param {{width: number, height: number}} hostSize | 303 * @param {{width: number, height: number}} hostSize |
| 304 * @param {number} hostDpi |
312 * @param {{width: number, height: number}} clientPluginSize | 305 * @param {{width: number, height: number}} clientPluginSize |
313 * @param {{width: number, height: number}} clientWindowSize | 306 * @param {{width: number, height: number}} clientWindowSize |
| 307 * @param {number} clientDpi |
314 * @param {boolean} clientFullscreen | 308 * @param {boolean} clientFullscreen |
315 * @return {remoting.ChromotingEvent} | 309 * @return {remoting.ChromotingEvent} |
316 * @private | 310 * @private |
317 */ | 311 */ |
318 remoting.SessionLogger.prototype.makeScreenResolutions_ = | 312 remoting.SessionLogger.prototype.makeScreenResolutions_ = |
319 function(hostSize, hostDpi, clientPluginSize, clientWindowSize, clientDpi, | 313 function(hostSize, hostDpi, clientPluginSize, clientWindowSize, clientDpi, |
320 clientFullscreen) { | 314 clientFullscreen) { |
321 var entry = new remoting.ChromotingEvent( | 315 var entry = new remoting.ChromotingEvent( |
322 remoting.ChromotingEvent.Type.SCREEN_RESOLUTIONS); | 316 remoting.ChromotingEvent.Type.SCREEN_RESOLUTIONS); |
323 entry.client_video_size = new remoting.ChromotingEvent.ScreenResolution( | 317 entry.client_video_size = new remoting.ChromotingEvent.ScreenResolution( |
(...skipping 23 matching lines...) Expand all Loading... |
347 * @private | 341 * @private |
348 */ | 342 */ |
349 remoting.SessionLogger.prototype.makeSessionIdOld_ = function() { | 343 remoting.SessionLogger.prototype.makeSessionIdOld_ = function() { |
350 var entry = new remoting.ChromotingEvent( | 344 var entry = new remoting.ChromotingEvent( |
351 remoting.ChromotingEvent.Type.SESSION_ID_OLD); | 345 remoting.ChromotingEvent.Type.SESSION_ID_OLD); |
352 this.fillEvent_(entry); | 346 this.fillEvent_(entry); |
353 return entry; | 347 return entry; |
354 }; | 348 }; |
355 | 349 |
356 /** | 350 /** |
357 * @return {remoting.ChromotingEvent} | 351 * @param {!remoting.ClientSession.PerfStats} perfStats |
| 352 * @return {!remoting.ChromotingEvent} |
358 * @private | 353 * @private |
359 */ | 354 */ |
360 remoting.SessionLogger.prototype.makeStats_ = function() { | 355 remoting.SessionLogger.prototype.makeStats_ = function(perfStats) { |
361 var perfStats = this.statsAccumulator_.getPerfStats(); | 356 var entry = new remoting.ChromotingEvent( |
362 if (Boolean(perfStats)) { | 357 remoting.ChromotingEvent.Type.CONNECTION_STATISTICS); |
363 var entry = new remoting.ChromotingEvent( | 358 this.fillEvent_(entry); |
364 remoting.ChromotingEvent.Type.CONNECTION_STATISTICS); | 359 entry.video_bandwidth = perfStats.videoBandwidth; |
365 this.fillEvent_(entry); | 360 entry.capture_latency = perfStats.captureLatency; |
366 entry.video_bandwidth = perfStats.videoBandwidth; | 361 entry.encode_latency = perfStats.encodeLatency; |
367 entry.capture_latency = perfStats.captureLatency; | 362 entry.decode_latency = perfStats.decodeLatency; |
368 entry.encode_latency = perfStats.encodeLatency; | 363 entry.render_latency = perfStats.renderLatency; |
369 entry.decode_latency = perfStats.decodeLatency; | 364 entry.roundtrip_latency = perfStats.roundtripLatency; |
370 entry.render_latency = perfStats.renderLatency; | 365 entry.max_capture_latency = perfStats.maxCaptureLatency; |
371 entry.roundtrip_latency = perfStats.roundtripLatency; | 366 entry.max_encode_latency = perfStats.maxEncodeLatency; |
372 entry.max_capture_latency = perfStats.maxCaptureLatency; | 367 entry.max_decode_latency = perfStats.maxDecodeLatency; |
373 entry.max_encode_latency = perfStats.maxEncodeLatency; | 368 entry.max_render_latency = perfStats.maxRenderLatency; |
374 entry.max_decode_latency = perfStats.maxDecodeLatency; | 369 entry.max_roundtrip_latency = perfStats.maxRoundtripLatency; |
375 entry.max_render_latency = perfStats.maxRenderLatency; | 370 return entry; |
376 entry.max_roundtrip_latency = perfStats.maxRoundtripLatency; | |
377 return entry; | |
378 } | |
379 return null; | |
380 }; | 371 }; |
381 | 372 |
382 /** | |
383 * Moves connection statistics from the accumulator to the log server. | |
384 * | |
385 * If all the statistics are zero, then the accumulator is still emptied, | |
386 * but the statistics are not sent to the log server. | |
387 * | |
388 * @private | |
389 */ | |
390 remoting.SessionLogger.prototype.logAccumulatedStatistics_ = function() { | |
391 var entry = this.makeStats_(); | |
392 if (entry) { | |
393 this.log_(entry); | |
394 } | |
395 this.statsAccumulator_.empty(); | |
396 }; | |
397 | 373 |
398 /** | 374 /** |
399 * @param {remoting.ChromotingEvent} entry | 375 * @param {remoting.ChromotingEvent} entry |
400 * @private | 376 * @private |
401 */ | 377 */ |
402 remoting.SessionLogger.prototype.fillEvent_ = function(entry) { | 378 remoting.SessionLogger.prototype.fillEvent_ = function(entry) { |
403 entry.session_id = this.sessionId_; | 379 entry.session_id = this.sessionId_; |
404 entry.mode = this.mode_; | 380 entry.mode = this.mode_; |
405 entry.role = this.role_; | 381 entry.role = this.role_; |
406 entry.session_entry_point = this.entryPoint_; | 382 entry.session_entry_point = this.entryPoint_; |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
551 case 'relay': | 527 case 'relay': |
552 return remoting.ChromotingEvent.ConnectionType.RELAY; | 528 return remoting.ChromotingEvent.ConnectionType.RELAY; |
553 default: | 529 default: |
554 throw new Error('Unknown ConnectionType :=' + type); | 530 throw new Error('Unknown ConnectionType :=' + type); |
555 } | 531 } |
556 } | 532 } |
557 | 533 |
558 // The maximum age of a session ID, in milliseconds. | 534 // The maximum age of a session ID, in milliseconds. |
559 remoting.SessionLogger.MAX_SESSION_ID_AGE = 24 * 60 * 60 * 1000; | 535 remoting.SessionLogger.MAX_SESSION_ID_AGE = 24 * 60 * 60 * 1000; |
560 | 536 |
561 // The time over which to accumulate connection statistics before logging them | |
562 // to the server, in milliseconds. | |
563 remoting.SessionLogger.CONNECTION_STATS_ACCUMULATE_TIME = 60 * 1000; | |
564 | |
565 })(); | 537 })(); |
OLD | NEW |