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';
45 signalStrategy.sendConnectionSetupResults(this);
48 // Constants used for generating a session ID.
50 remoting.LogToServer.SESSION_ID_ALPHABET_ =
51 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
53 remoting.LogToServer.SESSION_ID_LEN_ = 20;
56 * Logs a client session state change.
58 * @param {remoting.ClientSession.State} state
59 * @param {!remoting.Error} connectionError
61 remoting.LogToServer.prototype.logClientSessionStateChange =
62 function(state, connectionError) {
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_);
72 // Don't accumulate connection statistics across state changes.
73 this.logAccumulatedStatistics_();
74 this.statsAccumulator_.empty();
75 // Maybe clear the session ID.
76 if (remoting.LogToServer.isEndOfSession_(state)) {
77 this.clearSessionId_();
82 * Set the connection type (direct, stun relay).
84 * @param {string} connectionType
86 remoting.LogToServer.prototype.setConnectionType = function(connectionType) {
87 this.connectionType_ = connectionType;
91 * @param {remoting.ChromotingEvent.Mode} mode
93 remoting.LogToServer.prototype.setLogEntryMode = function(mode) {
95 case remoting.ChromotingEvent.Mode.IT2ME:
96 this.logEntryMode_ = remoting.ServerLogEntry.VALUE_MODE_IT2ME;
98 case remoting.ChromotingEvent.Mode.ME2ME:
99 this.logEntryMode_ = remoting.ServerLogEntry.VALUE_MODE_ME2ME;
101 case remoting.ChromotingEvent.Mode.LGAPP:
102 this.logEntryMode_ = remoting.ServerLogEntry.VALUE_MODE_APP_REMOTING;
105 this.logEntryMode_ = remoting.ServerLogEntry.VALUE_MODE_UNKNOWN;
110 * @param {remoting.SignalStrategy.Type} strategyType
111 * @param {remoting.FallbackSignalStrategy.Progress} progress
113 remoting.LogToServer.prototype.logSignalStrategyProgress =
114 function(strategyType, progress) {
115 this.maybeExpireSessionId_();
116 var entry = remoting.ServerLogEntry.makeSignalStrategyProgress(
117 this.sessionId_, strategyType, progress);
122 * @return {string} The current session id. This is random GUID, refreshed
125 remoting.LogToServer.prototype.getSessionId = function() {
126 return this.sessionId_;
130 * Whether a session state is one of the states that occurs at the end of
134 * @param {remoting.ClientSession.State} state
137 remoting.LogToServer.isEndOfSession_ = function(state) {
138 return ((state == remoting.ClientSession.State.CLOSED) ||
139 (state == remoting.ClientSession.State.FAILED) ||
140 (state == remoting.ClientSession.State.CONNECTION_DROPPED) ||
141 (state == remoting.ClientSession.State.CONNECTION_CANCELED));
146 * Logs connection statistics.
147 * @param {Object<number>} stats The connection statistics
149 remoting.LogToServer.prototype.logStatistics = function(stats) {
150 this.maybeExpireSessionId_();
151 // Store the statistics.
152 this.statsAccumulator_.add(stats);
153 // Send statistics to the server if they've been accumulating for at least
155 if (this.statsAccumulator_.getTimeSinceFirstValue() >=
156 remoting.Logger.CONNECTION_STATS_ACCUMULATE_TIME) {
157 this.logAccumulatedStatistics_();
162 * Moves connection statistics from the accumulator to the log server.
164 * If all the statistics are zero, then the accumulator is still emptied,
165 * but the statistics are not sent to the log server.
169 remoting.LogToServer.prototype.logAccumulatedStatistics_ = function() {
170 var entry = remoting.ServerLogEntry.makeStats(this.statsAccumulator_,
171 this.connectionType_,
174 entry.addClientOSFields();
175 entry.addChromeVersionField();
176 entry.addWebappVersionField();
177 entry.addSessionIdField(this.sessionId_);
180 this.statsAccumulator_.empty();
184 * Sends a log entry to the server.
187 * @param {remoting.ServerLogEntry} entry
189 remoting.LogToServer.prototype.log_ = function(entry) {
190 // Log the time taken to get to this point from the time this session started.
191 // Exclude time taken for authorization.
192 var sessionDurationInSeconds =
193 (new Date().getTime() - this.sessionStartTime_ -
194 this.authTotalTime_) / 1000.0;
195 entry.addSessionDuration(sessionDurationInSeconds);
196 entry.addApplicationId();
197 // The host-version will be blank for logs before a session has been created.
198 // For example, the signal-strategy log-entries won't have host version info.
199 entry.addHostVersion(this.hostVersion_);
201 // Send the stanza to the debug log.
202 console.log('Enqueueing log entry:');
205 var stanza = '<cli:iq to="' + remoting.settings.DIRECTORY_BOT_JID + '" ' +
206 'type="set" xmlns:cli="jabber:client">' +
207 '<gr:log xmlns:gr="google:remoting">' +
211 this.signalStrategy_.sendMessage(stanza);
215 * Sets the session ID to a random string.
217 remoting.LogToServer.prototype.setSessionId = function() {
218 this.sessionId_ = remoting.LogToServer.generateSessionId_();
219 this.sessionIdGenerationTime_ = new Date().getTime();
223 * Clears the session ID.
227 remoting.LogToServer.prototype.clearSessionId_ = function() {
228 this.sessionId_ = '';
229 this.sessionIdGenerationTime_ = 0;
233 * Sets a new session ID, if the current session ID has reached its maximum age.
235 * This method also logs the old and new session IDs to the server, in separate
240 remoting.LogToServer.prototype.maybeExpireSessionId_ = function() {
241 if ((this.sessionId_ != '') &&
242 (new Date().getTime() - this.sessionIdGenerationTime_ >=
243 remoting.Logger.MAX_SESSION_ID_AGE)) {
244 // Log the old session ID.
245 var entry = remoting.ServerLogEntry.makeSessionIdOld(this.sessionId_,
248 // Generate a new session ID.
250 // Log the new session ID.
251 entry = remoting.ServerLogEntry.makeSessionIdNew(this.sessionId_,
258 * Generates a string that can be used as a session ID.
261 * @return {string} a session ID
263 remoting.LogToServer.generateSessionId_ = function() {
265 for (var i = 0; i < remoting.LogToServer.SESSION_ID_LEN_; i++) {
267 Math.random() * remoting.LogToServer.SESSION_ID_ALPHABET_.length;
269 remoting.LogToServer.SESSION_ID_ALPHABET_.slice(index, index + 1));
271 return idArray.join('');
275 * @param {number} totalTime The value of time taken to complete authorization.
276 * @return {void} Nothing.
278 remoting.LogToServer.prototype.setAuthTotalTime = function(totalTime) {
279 this.authTotalTime_ = totalTime;
283 * @param {string} hostVersion Version of the host for current session.
284 * @return {void} Nothing.
286 remoting.LogToServer.prototype.setHostVersion = function(hostVersion) {
287 this.hostVersion_ = hostVersion;