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 * Module for sending log entries to the server.
12 /** @suppress {duplicate} */
13 var remoting
= remoting
|| {};
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.
20 * @implements {remoting.Logger}
22 remoting
.LogToServer = function(signalStrategy
, opt_isHost
) {
24 this.statsAccumulator_
= new remoting
.StatsAccumulator();
28 this.sessionIdGenerationTime_
= 0;
30 this.sessionStartTime_
= new Date().getTime();
32 this.signalStrategy_
= signalStrategy
;
33 /** @private {string} */
34 this.connectionType_
= '';
36 this.authTotalTime_
= 0;
37 /** @private {string} */
38 this.hostVersion_
= '';
40 this.logEntryMode_
= remoting
.ServerLogEntry
.VALUE_MODE_UNKNOWN
;
42 this.role_
= opt_isHost
? 'host' : 'client';
47 // Constants used for generating a session ID.
49 remoting
.LogToServer
.SESSION_ID_ALPHABET_
=
50 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
52 remoting
.LogToServer
.SESSION_ID_LEN_
= 20;
55 * Logs a client session state change.
57 * @param {remoting.ClientSession.State} state
58 * @param {!remoting.Error} connectionError
59 * @param {?remoting.ChromotingEvent.XmppError} xmppError
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
);
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_();
84 * Set the connection type (direct, stun relay).
86 * @param {string} connectionType
88 remoting
.LogToServer
.prototype.setConnectionType = function(connectionType
) {
89 this.connectionType_
= connectionType
;
93 * @param {remoting.ChromotingEvent.Mode} mode
95 remoting
.LogToServer
.prototype.setLogEntryMode = function(mode
) {
97 case remoting
.ChromotingEvent
.Mode
.IT2ME
:
98 this.logEntryMode_
= remoting
.ServerLogEntry
.VALUE_MODE_IT2ME
;
100 case remoting
.ChromotingEvent
.Mode
.ME2ME
:
101 this.logEntryMode_
= remoting
.ServerLogEntry
.VALUE_MODE_ME2ME
;
103 case remoting
.ChromotingEvent
.Mode
.LGAPP
:
104 this.logEntryMode_
= remoting
.ServerLogEntry
.VALUE_MODE_APP_REMOTING
;
107 this.logEntryMode_
= remoting
.ServerLogEntry
.VALUE_MODE_UNKNOWN
;
112 * @param {remoting.SignalStrategy.Type} strategyType
113 * @param {remoting.FallbackSignalStrategy.Progress} progress
115 remoting
.LogToServer
.prototype.logSignalStrategyProgress
=
116 function(strategyType
, progress
) {
117 this.maybeExpireSessionId_();
118 var entry
= remoting
.ServerLogEntry
.makeSignalStrategyProgress(
119 this.sessionId_
, strategyType
, progress
);
124 * @return {string} The current session id. This is random GUID, refreshed
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
136 * @param {remoting.ClientSession.State} state
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
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
157 if (this.statsAccumulator_
.getTimeSinceFirstValue() >=
158 remoting
.Logger
.CONNECTION_STATS_ACCUMULATE_TIME
) {
159 this.logAccumulatedStatistics_();
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.
171 remoting
.LogToServer
.prototype.logAccumulatedStatistics_ = function() {
172 var entry
= remoting
.ServerLogEntry
.makeStats(this.statsAccumulator_
,
173 this.connectionType_
,
176 entry
.addClientOSFields();
177 entry
.addChromeVersionField();
178 entry
.addWebappVersionField();
179 entry
.addSessionIdField(this.sessionId_
);
182 this.statsAccumulator_
.empty();
186 * Sends a log entry to the server.
189 * @param {remoting.ServerLogEntry} entry
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:');
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">' +
213 this.signalStrategy_
.sendMessage(stanza
);
217 * Sets the session ID to a random string.
219 remoting
.LogToServer
.prototype.setSessionId = function() {
220 this.sessionId_
= remoting
.LogToServer
.generateSessionId_();
221 this.sessionIdGenerationTime_
= new Date().getTime();
225 * Clears the session ID.
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
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_
,
250 // Generate a new session ID.
252 // Log the new session ID.
253 entry
= remoting
.ServerLogEntry
.makeSessionIdNew(this.sessionId_
,
260 * Generates a string that can be used as a session ID.
263 * @return {string} a session ID
265 remoting
.LogToServer
.generateSessionId_ = function() {
267 for (var i
= 0; i
< remoting
.LogToServer
.SESSION_ID_LEN_
; i
++) {
269 Math
.random() * remoting
.LogToServer
.SESSION_ID_ALPHABET_
.length
;
271 remoting
.LogToServer
.SESSION_ID_ALPHABET_
.slice(index
, index
+ 1));
273 return idArray
.join('');
277 * @param {number} totalTime The value of time taken to complete authorization.
278 * @return {void} Nothing.
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.
288 remoting
.LogToServer
.prototype.setHostVersion = function(hostVersion
) {
289 this.hostVersion_
= hostVersion
;