| 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 |