Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / remoting / webapp / base / js / log_to_server.js
blobc77cc9893a41bac285a499cfcde3f6e901f6b501
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.
5 /**
6  * @fileoverview
7  * Module for sending log entries to the server.
8  */
10 'use strict';
12 /** @suppress {duplicate} */
13 var remoting = remoting || {};
15 /**
16  * @param {remoting.SignalStrategy} signalStrategy Signal strategy.
17  * @param {boolean=} opt_isHost True if this instance should log role=host
18  *     events rather than role=client.
19  * @constructor
20  * @implements {remoting.Logger}
21  */
22 remoting.LogToServer = function(signalStrategy, opt_isHost) {
23   /** @private */
24   this.statsAccumulator_ = new remoting.StatsAccumulator();
25   /** @private */
26   this.sessionId_ = '';
27   /** @private */
28   this.sessionIdGenerationTime_ = 0;
29   /** @private */
30   this.sessionStartTime_ = new Date().getTime();
31   /** @private */
32   this.signalStrategy_ = signalStrategy;
33   /** @private {string} */
34   this.connectionType_ = '';
35   /** @private */
36   this.authTotalTime_ = 0;
37   /** @private {string} */
38   this.hostVersion_ = '';
39   /** @private */
40   this.logEntryMode_ = remoting.ServerLogEntry.VALUE_MODE_UNKNOWN;
41   /** @private */
42   this.role_ = opt_isHost ? 'host' : 'client';
44   this.setSessionId();
47 // Constants used for generating a session ID.
48 /** @private */
49 remoting.LogToServer.SESSION_ID_ALPHABET_ =
50     'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
51 /** @private */
52 remoting.LogToServer.SESSION_ID_LEN_ = 20;
54 /**
55  * Logs a client session state change.
56  *
57  * @param {remoting.ClientSession.State} state
58  * @param {!remoting.Error} connectionError
59  * @param {?remoting.ChromotingEvent.XmppError} xmppError
60  */
61 remoting.LogToServer.prototype.logClientSessionStateChange =
62     function(state, connectionError, xmppError) {
63   this.maybeExpireSessionId_();
64   // Log the session state change.
65   var entry = remoting.ServerLogEntry.makeClientSessionStateChange(
66       state, connectionError, this.logEntryMode_, this.role_);
67   entry.addClientOSFields();
68   entry.addChromeVersionField();
69   entry.addWebappVersionField();
70   entry.addSessionIdField(this.sessionId_);
71   entry.addXmppError(xmppError);
73   this.log_(entry);
74   // Don't accumulate connection statistics across state changes.
75   this.logAccumulatedStatistics_();
76   this.statsAccumulator_.empty();
77   // Maybe clear the session ID.
78   if (remoting.LogToServer.isEndOfSession_(state)) {
79     this.clearSessionId_();
80   }
83 /**
84  * Set the connection type (direct, stun relay).
85  *
86  * @param {string} connectionType
87  */
88 remoting.LogToServer.prototype.setConnectionType = function(connectionType) {
89   this.connectionType_ = connectionType;
92 /**
93  * @param {remoting.ChromotingEvent.Mode} mode
94  */
95 remoting.LogToServer.prototype.setLogEntryMode = function(mode) {
96   switch (mode) {
97     case remoting.ChromotingEvent.Mode.IT2ME:
98       this.logEntryMode_ = remoting.ServerLogEntry.VALUE_MODE_IT2ME;
99       break;
100     case remoting.ChromotingEvent.Mode.ME2ME:
101       this.logEntryMode_ = remoting.ServerLogEntry.VALUE_MODE_ME2ME;
102       break;
103     case remoting.ChromotingEvent.Mode.LGAPP:
104       this.logEntryMode_ = remoting.ServerLogEntry.VALUE_MODE_APP_REMOTING;
105       break;
106     default:
107       this.logEntryMode_ = remoting.ServerLogEntry.VALUE_MODE_UNKNOWN;
108   }
112  * @param {remoting.SignalStrategy.Type} strategyType
113  * @param {remoting.FallbackSignalStrategy.Progress} progress
114  */
115 remoting.LogToServer.prototype.logSignalStrategyProgress =
116     function(strategyType, progress) {
117   this.maybeExpireSessionId_();
118   var entry = remoting.ServerLogEntry.makeSignalStrategyProgress(
119       this.sessionId_, strategyType, progress);
120   this.log_(entry);
124  * @return {string} The current session id. This is random GUID, refreshed
125  *     every 24hrs.
126  */
127 remoting.LogToServer.prototype.getSessionId = function() {
128   return this.sessionId_;
132  * Whether a session state is one of the states that occurs at the end of
133  * a session.
135  * @private
136  * @param {remoting.ClientSession.State} state
137  * @return {boolean}
138  */
139 remoting.LogToServer.isEndOfSession_ = function(state) {
140   return ((state == remoting.ClientSession.State.CLOSED) ||
141       (state == remoting.ClientSession.State.FAILED) ||
142       (state == remoting.ClientSession.State.CONNECTION_DROPPED) ||
143       (state == remoting.ClientSession.State.CONNECTION_CANCELED));
148  * Logs connection statistics.
149  * @param {Object<number>} stats The connection statistics
150  */
151 remoting.LogToServer.prototype.logStatistics = function(stats) {
152   this.maybeExpireSessionId_();
153   // Store the statistics.
154   this.statsAccumulator_.add(stats);
155   // Send statistics to the server if they've been accumulating for at least
156   // 60 seconds.
157   if (this.statsAccumulator_.getTimeSinceFirstValue() >=
158       remoting.Logger.CONNECTION_STATS_ACCUMULATE_TIME) {
159     this.logAccumulatedStatistics_();
160   }
164  * Moves connection statistics from the accumulator to the log server.
166  * If all the statistics are zero, then the accumulator is still emptied,
167  * but the statistics are not sent to the log server.
169  * @private
170  */
171 remoting.LogToServer.prototype.logAccumulatedStatistics_ = function() {
172   var entry = remoting.ServerLogEntry.makeStats(this.statsAccumulator_,
173                                                 this.connectionType_,
174                                                 this.logEntryMode_);
175   if (entry) {
176     entry.addClientOSFields();
177     entry.addChromeVersionField();
178     entry.addWebappVersionField();
179     entry.addSessionIdField(this.sessionId_);
180     this.log_(entry);
181   }
182   this.statsAccumulator_.empty();
186  * Sends a log entry to the server.
188  * @private
189  * @param {remoting.ServerLogEntry} entry
190  */
191 remoting.LogToServer.prototype.log_ = function(entry) {
192   // Log the time taken to get to this point from the time this session started.
193   // Exclude time taken for authorization.
194   var sessionDurationInSeconds =
195       (new Date().getTime() - this.sessionStartTime_ -
196           this.authTotalTime_) / 1000.0;
197   entry.addSessionDuration(sessionDurationInSeconds);
198   entry.addApplicationId();
199   // The host-version will be blank for logs before a session has been created.
200   // For example, the signal-strategy log-entries won't have host version info.
201   entry.addHostVersion(this.hostVersion_);
203   // Send the stanza to the debug log.
204   console.log('Enqueueing log entry:');
205   entry.toDebugLog(1);
207   var stanza = '<cli:iq to="' + remoting.settings.DIRECTORY_BOT_JID + '" ' +
208                        'type="set" xmlns:cli="jabber:client">' +
209                  '<gr:log xmlns:gr="google:remoting">' +
210                    entry.toStanza() +
211                  '</gr:log>' +
212                '</cli:iq>';
213   this.signalStrategy_.sendMessage(stanza);
217  * Sets the session ID to a random string.
218  */
219 remoting.LogToServer.prototype.setSessionId = function() {
220   this.sessionId_ = remoting.LogToServer.generateSessionId_();
221   this.sessionIdGenerationTime_ = new Date().getTime();
225  * Clears the session ID.
227  * @private
228  */
229 remoting.LogToServer.prototype.clearSessionId_ = function() {
230   this.sessionId_ = '';
231   this.sessionIdGenerationTime_ = 0;
235  * Sets a new session ID, if the current session ID has reached its maximum age.
237  * This method also logs the old and new session IDs to the server, in separate
238  * log entries.
240  * @private
241  */
242 remoting.LogToServer.prototype.maybeExpireSessionId_ = function() {
243   if ((this.sessionId_ != '') &&
244       (new Date().getTime() - this.sessionIdGenerationTime_ >=
245       remoting.Logger.MAX_SESSION_ID_AGE)) {
246     // Log the old session ID.
247     var entry = remoting.ServerLogEntry.makeSessionIdOld(this.sessionId_,
248                                                          this.logEntryMode_);
249     this.log_(entry);
250     // Generate a new session ID.
251     this.setSessionId();
252     // Log the new session ID.
253     entry = remoting.ServerLogEntry.makeSessionIdNew(this.sessionId_,
254                                                      this.logEntryMode_);
255     this.log_(entry);
256   }
260  * Generates a string that can be used as a session ID.
262  * @private
263  * @return {string} a session ID
264  */
265 remoting.LogToServer.generateSessionId_ = function() {
266   var idArray = [];
267   for (var i = 0; i < remoting.LogToServer.SESSION_ID_LEN_; i++) {
268     var index =
269         Math.random() * remoting.LogToServer.SESSION_ID_ALPHABET_.length;
270     idArray.push(
271         remoting.LogToServer.SESSION_ID_ALPHABET_.slice(index, index + 1));
272   }
273   return idArray.join('');
277  * @param {number} totalTime The value of time taken to complete authorization.
278  * @return {void} Nothing.
279  */
280 remoting.LogToServer.prototype.setAuthTotalTime = function(totalTime) {
281   this.authTotalTime_ = totalTime;
285  * @param {string} hostVersion Version of the host for current session.
286  * @return {void} Nothing.
287  */
288 remoting.LogToServer.prototype.setHostVersion = function(hostVersion) {
289   this.hostVersion_ = hostVersion;