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;