1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
7 * A class of server log entries.
9 * Any changes to the values here need to be coordinated with the host and
10 * server/log proto code.
11 * See remoting/signaling/server_log_entry.{cc|h}
16 /** @suppress {duplicate} */
17 var remoting = remoting || {};
23 remoting.ServerLogEntry = function() {
24 /** @type Object<string> */ this.dict = {};
28 remoting.ServerLogEntry.KEY_EVENT_NAME_ = 'event-name';
30 remoting.ServerLogEntry.VALUE_EVENT_NAME_SESSION_STATE_ = 'session-state';
32 remoting.ServerLogEntry.VALUE_EVENT_NAME_SIGNAL_STRATEGY_PROGRESS_ =
33 'signal-strategy-progress';
35 remoting.ServerLogEntry.KEY_SESSION_ID_ = 'session-id';
37 remoting.ServerLogEntry.KEY_ROLE_ = 'role';
39 remoting.ServerLogEntry.VALUE_ROLE_CLIENT_ = 'client';
41 remoting.ServerLogEntry.KEY_SESSION_STATE_ = 'session-state';
43 remoting.ServerLogEntry.KEY_CONNECTION_TYPE_ = 'connection-type';
45 remoting.ServerLogEntry.KEY_SIGNAL_STRATEGY_TYPE_ = 'signal-strategy-type';
47 remoting.ServerLogEntry.KEY_SIGNAL_STRATEGY_PROGRESS_ =
48 'signal-strategy-progress';
50 remoting.ServerLogEntry.KEY_SESSION_DURATION_SECONDS_ = 'session-duration';
53 remoting.ServerLogEntry.KEY_XMPP_ERROR_RAW_STANZA = 'xmpp-error-raw-stanza';
57 * @param {remoting.ClientSession.State} state
60 remoting.ServerLogEntry.getValueForSessionState_ = function(state) {
62 case remoting.ClientSession.State.UNKNOWN:
64 case remoting.ClientSession.State.INITIALIZING:
65 return 'initializing';
66 case remoting.ClientSession.State.CONNECTING:
68 case remoting.ClientSession.State.AUTHENTICATED:
69 return 'authenticated';
70 case remoting.ClientSession.State.CONNECTED:
72 case remoting.ClientSession.State.CLOSED:
74 case remoting.ClientSession.State.FAILED:
75 return 'connection-failed';
76 case remoting.ClientSession.State.CONNECTION_DROPPED:
77 return 'connection-dropped';
78 case remoting.ClientSession.State.CONNECTION_CANCELED:
79 return 'connection-canceled';
81 return 'undefined-' + state;
86 remoting.ServerLogEntry.KEY_CONNECTION_ERROR_ = 'connection-error';
90 * @param {!remoting.Error} connectionError
93 remoting.ServerLogEntry.getValueForError_ = function(connectionError) {
94 // Directory service should be updated if a new string is added here as
95 // otherwise the error code will be ignored (i.e. recorded as 0 instead).
96 switch (connectionError.getTag()) {
97 case remoting.Error.Tag.NONE:
99 case remoting.Error.Tag.INVALID_ACCESS_CODE:
100 return 'invalid-access-code';
101 case remoting.Error.Tag.MISSING_PLUGIN:
102 return 'missing_plugin';
103 case remoting.Error.Tag.AUTHENTICATION_FAILED:
104 return 'authentication-failed';
105 case remoting.Error.Tag.HOST_IS_OFFLINE:
106 return 'host-is-offline';
107 case remoting.Error.Tag.INCOMPATIBLE_PROTOCOL:
108 return 'incompatible-protocol';
109 case remoting.Error.Tag.BAD_PLUGIN_VERSION:
110 return 'bad-plugin-version';
111 case remoting.Error.Tag.NETWORK_FAILURE:
112 return 'network-failure';
113 case remoting.Error.Tag.HOST_OVERLOAD:
114 return 'host-overload';
115 case remoting.Error.Tag.P2P_FAILURE:
116 return 'p2p-failure';
117 case remoting.Error.Tag.CLIENT_SUSPENDED:
118 return 'client-suspended';
119 case remoting.Error.Tag.UNEXPECTED:
122 return 'unknown-' + connectionError.getTag();
127 remoting.ServerLogEntry.VALUE_EVENT_NAME_CONNECTION_STATISTICS_ =
128 "connection-statistics";
130 remoting.ServerLogEntry.KEY_VIDEO_BANDWIDTH_ = "video-bandwidth";
132 remoting.ServerLogEntry.KEY_CAPTURE_LATENCY_ = "capture-latency";
134 remoting.ServerLogEntry.KEY_ENCODE_LATENCY_ = "encode-latency";
136 remoting.ServerLogEntry.KEY_DECODE_LATENCY_ = "decode-latency";
138 remoting.ServerLogEntry.KEY_RENDER_LATENCY_ = "render-latency";
140 remoting.ServerLogEntry.KEY_ROUNDTRIP_LATENCY_ = "roundtrip-latency";
143 remoting.ServerLogEntry.KEY_OS_NAME_ = 'os-name';
146 remoting.ServerLogEntry.KEY_OS_VERSION_ = 'os-version';
149 remoting.ServerLogEntry.KEY_CPU_ = 'cpu';
152 remoting.ServerLogEntry.KEY_BROWSER_VERSION_ = 'browser-version';
155 remoting.ServerLogEntry.KEY_WEBAPP_VERSION_ = 'webapp-version';
158 remoting.ServerLogEntry.KEY_HOST_VERSION_ = 'host-version';
161 remoting.ServerLogEntry.VALUE_EVENT_NAME_SESSION_ID_OLD_ = 'session-id-old';
164 remoting.ServerLogEntry.VALUE_EVENT_NAME_SESSION_ID_NEW_ = 'session-id-new';
167 remoting.ServerLogEntry.KEY_MODE_ = 'mode';
168 // These values are passed in by the Activity to identify the current mode.
169 remoting.ServerLogEntry.VALUE_MODE_IT2ME = 'it2me';
170 remoting.ServerLogEntry.VALUE_MODE_ME2ME = 'me2me';
171 remoting.ServerLogEntry.VALUE_MODE_APP_REMOTING = 'lgapp';
172 remoting.ServerLogEntry.VALUE_MODE_UNKNOWN = 'unknown';
175 remoting.ServerLogEntry.KEY_APP_ID_ = 'application-id';
178 * Sets one field in this log entry.
181 * @param {string} key
182 * @param {string} value
184 remoting.ServerLogEntry.prototype.set_ = function(key, value) {
185 this.dict[key] = value;
189 * Converts this object into an XML stanza.
193 remoting.ServerLogEntry.prototype.toStanza = function() {
194 var stanza = '<gr:entry ';
195 for (var key in this.dict) {
196 stanza += escape(key) + '="' + escape(this.dict[key]) + '" ';
203 * Prints this object on the debug log.
205 * @param {number} indentLevel the indentation level
207 remoting.ServerLogEntry.prototype.toDebugLog = function(indentLevel) {
208 /** @type Array<string> */ var fields = [];
209 for (var key in this.dict) {
210 fields.push(key + ': ' + this.dict[key]);
212 console.log(Array(indentLevel+1).join(" ") + fields.join(', '));
216 * Makes a log entry for a change of client session state.
218 * @param {remoting.ClientSession.State} state
219 * @param {!remoting.Error} connectionError
220 * @param {string} mode The current app mode (It2Me, Me2Me, AppRemoting).
221 * @param {string} role 'client' if the app is acting as a Chromoting client
222 * or 'host' if it is acting as a host (IT2Me)
223 * @return {remoting.ServerLogEntry}
225 remoting.ServerLogEntry.makeClientSessionStateChange = function(state,
226 connectionError, mode, role) {
227 var entry = new remoting.ServerLogEntry();
228 entry.set_(remoting.ServerLogEntry.KEY_ROLE_, role);
229 entry.set_(remoting.ServerLogEntry.KEY_EVENT_NAME_,
230 remoting.ServerLogEntry.VALUE_EVENT_NAME_SESSION_STATE_);
231 entry.set_(remoting.ServerLogEntry.KEY_SESSION_STATE_,
232 remoting.ServerLogEntry.getValueForSessionState_(state));
233 if (!connectionError.isNone()) {
234 entry.set_(remoting.ServerLogEntry.KEY_CONNECTION_ERROR_,
235 remoting.ServerLogEntry.getValueForError_(connectionError));
237 entry.addModeField(mode);
242 * Makes a log entry for a set of connection statistics.
243 * Returns null if all the statistics were zero.
245 * @param {remoting.StatsAccumulator} statsAccumulator
246 * @param {string} connectionType
247 * @param {string} mode The current app mode (It2Me, Me2Me, AppRemoting).
248 * @return {?remoting.ServerLogEntry}
250 remoting.ServerLogEntry.makeStats = function(statsAccumulator,
251 connectionType, mode) {
252 var entry = new remoting.ServerLogEntry();
253 entry.set_(remoting.ServerLogEntry.KEY_ROLE_,
254 remoting.ServerLogEntry.VALUE_ROLE_CLIENT_);
255 entry.set_(remoting.ServerLogEntry.KEY_EVENT_NAME_,
256 remoting.ServerLogEntry.VALUE_EVENT_NAME_CONNECTION_STATISTICS_);
257 if (connectionType) {
258 entry.set_(remoting.ServerLogEntry.KEY_CONNECTION_TYPE_,
261 entry.addModeField(mode);
263 nonZero |= entry.addStatsField_(
264 remoting.ServerLogEntry.KEY_VIDEO_BANDWIDTH_,
265 remoting.ClientSession.STATS_KEY_VIDEO_BANDWIDTH, statsAccumulator);
266 nonZero |= entry.addStatsField_(
267 remoting.ServerLogEntry.KEY_CAPTURE_LATENCY_,
268 remoting.ClientSession.STATS_KEY_CAPTURE_LATENCY, statsAccumulator);
269 nonZero |= entry.addStatsField_(
270 remoting.ServerLogEntry.KEY_ENCODE_LATENCY_,
271 remoting.ClientSession.STATS_KEY_ENCODE_LATENCY, statsAccumulator);
272 nonZero |= entry.addStatsField_(
273 remoting.ServerLogEntry.KEY_DECODE_LATENCY_,
274 remoting.ClientSession.STATS_KEY_DECODE_LATENCY, statsAccumulator);
275 nonZero |= entry.addStatsField_(
276 remoting.ServerLogEntry.KEY_RENDER_LATENCY_,
277 remoting.ClientSession.STATS_KEY_RENDER_LATENCY, statsAccumulator);
278 nonZero |= entry.addStatsField_(
279 remoting.ServerLogEntry.KEY_ROUNDTRIP_LATENCY_,
280 remoting.ClientSession.STATS_KEY_ROUNDTRIP_LATENCY, statsAccumulator);
288 * Adds one connection statistic to a log entry.
291 * @param {string} entryKey
292 * @param {string} statsKey
293 * @param {remoting.StatsAccumulator} statsAccumulator
294 * @return {boolean} whether the statistic is non-zero
296 remoting.ServerLogEntry.prototype.addStatsField_ = function(
297 entryKey, statsKey, statsAccumulator) {
298 var val = statsAccumulator.calcMean(statsKey);
299 this.set_(entryKey, val.toFixed(2));
304 * Makes a log entry for a "this session ID is old" event.
306 * @param {string} sessionId
307 * @param {string} mode The current app mode (It2Me, Me2Me, AppRemoting).
308 * @return {remoting.ServerLogEntry}
310 remoting.ServerLogEntry.makeSessionIdOld = function(sessionId, mode) {
311 var entry = new remoting.ServerLogEntry();
312 entry.set_(remoting.ServerLogEntry.KEY_ROLE_,
313 remoting.ServerLogEntry.VALUE_ROLE_CLIENT_);
314 entry.set_(remoting.ServerLogEntry.KEY_EVENT_NAME_,
315 remoting.ServerLogEntry.VALUE_EVENT_NAME_SESSION_ID_OLD_);
316 entry.addSessionIdField(sessionId);
317 entry.addModeField(mode);
322 * Makes a log entry for a "this session ID is new" event.
324 * @param {string} sessionId
325 * @param {string} mode The current app mode (It2Me, Me2Me, AppRemoting).
326 * @return {remoting.ServerLogEntry}
328 remoting.ServerLogEntry.makeSessionIdNew = function(sessionId, mode) {
329 var entry = new remoting.ServerLogEntry();
330 entry.set_(remoting.ServerLogEntry.KEY_ROLE_,
331 remoting.ServerLogEntry.VALUE_ROLE_CLIENT_);
332 entry.set_(remoting.ServerLogEntry.KEY_EVENT_NAME_,
333 remoting.ServerLogEntry.VALUE_EVENT_NAME_SESSION_ID_NEW_);
334 entry.addSessionIdField(sessionId);
335 entry.addModeField(mode);
340 * Makes a log entry for a "signal strategy fallback" event.
342 * @param {string} sessionId
343 * @param {remoting.SignalStrategy.Type} strategyType
344 * @param {remoting.FallbackSignalStrategy.Progress} progress
345 * @return {remoting.ServerLogEntry}
347 remoting.ServerLogEntry.makeSignalStrategyProgress =
348 function(sessionId, strategyType, progress) {
349 var entry = new remoting.ServerLogEntry();
350 entry.set_(remoting.ServerLogEntry.KEY_ROLE_,
351 remoting.ServerLogEntry.VALUE_ROLE_CLIENT_);
353 remoting.ServerLogEntry.KEY_EVENT_NAME_,
354 remoting.ServerLogEntry.VALUE_EVENT_NAME_SIGNAL_STRATEGY_PROGRESS_);
355 entry.addSessionIdField(sessionId);
356 entry.set_(remoting.ServerLogEntry.KEY_SIGNAL_STRATEGY_TYPE_, strategyType);
357 entry.set_(remoting.ServerLogEntry.KEY_SIGNAL_STRATEGY_PROGRESS_, progress);
363 * Adds a session ID field to this log entry.
365 * @param {string} sessionId
367 remoting.ServerLogEntry.prototype.addSessionIdField = function(sessionId) {
368 this.set_(remoting.ServerLogEntry.KEY_SESSION_ID_, sessionId);
372 * Adds fields describing the host to this log entry.
374 remoting.ServerLogEntry.prototype.addClientOSFields = function() {
375 var systemInfo = remoting.getSystemInfo();
377 if (systemInfo.osName.length > 0) {
378 this.set_(remoting.ServerLogEntry.KEY_OS_NAME_, systemInfo.osName);
380 if (systemInfo.osVersion.length > 0) {
381 this.set_(remoting.ServerLogEntry.KEY_OS_VERSION_, systemInfo.osVersion);
383 if (systemInfo.cpu.length > 0) {
384 this.set_(remoting.ServerLogEntry.KEY_CPU_, systemInfo.cpu);
390 * Adds a field to this log entry specifying the time in seconds since the start
391 * of the session to the current event.
392 * @param {number} sessionDurationInSeconds
394 remoting.ServerLogEntry.prototype.addSessionDuration =
395 function(sessionDurationInSeconds) {
396 this.set_(remoting.ServerLogEntry.KEY_SESSION_DURATION_SECONDS_,
397 String(sessionDurationInSeconds));
402 * Adds a field specifying the browser version to this log entry.
404 remoting.ServerLogEntry.prototype.addChromeVersionField = function() {
405 var version = remoting.getChromeVersion();
406 if (version != null) {
407 this.set_(remoting.ServerLogEntry.KEY_BROWSER_VERSION_, version);
412 * Adds a field specifying the webapp version to this log entry.
414 remoting.ServerLogEntry.prototype.addWebappVersionField = function() {
415 var manifest = chrome.runtime.getManifest();
416 if (manifest && manifest.version) {
417 this.set_(remoting.ServerLogEntry.KEY_WEBAPP_VERSION_, manifest.version);
422 * Adds a field specifying the host version to this log entry.
423 * @param {string} hostVersion Version of the host for current session.
424 * @return {void} Nothing.
426 remoting.ServerLogEntry.prototype.addHostVersion = function(hostVersion) {
427 this.set_(remoting.ServerLogEntry.KEY_HOST_VERSION_, hostVersion);
431 * Adds a field specifying the mode to this log entry.
432 * @param {string} mode The current app mode (It2Me, Me2Me, AppRemoting).
434 remoting.ServerLogEntry.prototype.addModeField = function(mode) {
435 this.set_(remoting.ServerLogEntry.KEY_MODE_, mode);
439 * Adds a field specifying the application ID to this log entry.
440 * @return {void} Nothing.
442 remoting.ServerLogEntry.prototype.addApplicationId = function() {
443 this.set_(remoting.ServerLogEntry.KEY_APP_ID_, chrome.runtime.id);
447 * Adds a field specifying the XMPP error to this log entry.
448 * @param {?remoting.ChromotingEvent.XmppError} xmppError
449 * @return {void} Nothing.
451 remoting.ServerLogEntry.prototype.addXmppError = function(xmppError) {
452 if (!Boolean(xmppError)) {
455 this.set_(remoting.ServerLogEntry.KEY_XMPP_ERROR_RAW_STANZA,
456 xmppError.raw_stanza);