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.
19 remoting.LogToServer = function(signalStrategy) {
21 this.statsAccumulator_ = new remoting.StatsAccumulator();
25 this.sessionIdGenerationTime_ = 0;
27 this.sessionStartTime_ = 0;
29 this.signalStrategy_ = signalStrategy;
32 // Constants used for generating a session ID.
34 remoting.LogToServer.SESSION_ID_ALPHABET_ =
35 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
37 remoting.LogToServer.SESSION_ID_LEN_ = 20;
39 // The maximum age of a session ID, in milliseconds.
40 remoting.LogToServer.MAX_SESSION_ID_AGE = 24 * 60 * 60 * 1000;
42 // The time over which to accumulate connection statistics before logging them
43 // to the server, in milliseconds.
44 remoting.LogToServer.CONNECTION_STATS_ACCUMULATE_TIME = 60 * 1000;
47 * Logs a client session state change.
49 * @param {remoting.ClientSession.State} state
50 * @param {remoting.Error} connectionError
51 * @param {remoting.ClientSession.Mode} mode
53 remoting.LogToServer.prototype.logClientSessionStateChange =
54 function(state, connectionError, mode) {
55 this.maybeExpireSessionId(mode);
56 // Maybe set the session ID and start time.
57 if (remoting.LogToServer.isStartOfSession(state)) {
58 if (this.sessionId_ == '') {
61 if (this.sessionStartTime_ == 0) {
62 this.sessionStartTime_ = new Date().getTime();
65 // Log the session state change.
66 var entry = remoting.ServerLogEntry.makeClientSessionStateChange(
67 state, connectionError, mode);
68 entry.addHostFields();
69 entry.addChromeVersionField();
70 entry.addWebappVersionField();
71 entry.addSessionIdField(this.sessionId_);
72 // Maybe clear the session start time, and log the session duration.
73 if (remoting.LogToServer.shouldAddDuration(state) &&
74 (this.sessionStartTime_ != 0)) {
75 entry.addSessionDurationField(
76 (new Date().getTime() - this.sessionStartTime_) / 1000.0);
77 if (remoting.LogToServer.isEndOfSession(state)) {
78 this.sessionStartTime_ = 0;
82 // Don't accumulate connection statistics across state changes.
83 this.logAccumulatedStatistics(mode);
84 this.statsAccumulator_.empty();
85 // Maybe clear the session ID.
86 if (remoting.LogToServer.isEndOfSession(state)) {
87 this.clearSessionId();
92 * Whether a session state is one of the states that occurs at the start of
96 * @param {remoting.ClientSession.State} state
99 remoting.LogToServer.isStartOfSession = function(state) {
100 return ((state == remoting.ClientSession.State.CONNECTING) ||
101 (state == remoting.ClientSession.State.INITIALIZING) ||
102 (state == remoting.ClientSession.State.CONNECTED));
106 * Whether a session state is one of the states that occurs at the end of
110 * @param {remoting.ClientSession.State} state
113 remoting.LogToServer.isEndOfSession = function(state) {
114 return ((state == remoting.ClientSession.State.CLOSED) ||
115 (state == remoting.ClientSession.State.FAILED) ||
116 (state == remoting.ClientSession.State.CONNECTION_DROPPED) ||
117 (state == remoting.ClientSession.State.CONNECTION_CANCELED));
121 * Whether the duration should be added to the log entry for this state.
124 * @param {remoting.ClientSession.State} state
127 remoting.LogToServer.shouldAddDuration = function(state) {
128 // Duration is added to log entries at the end of the session, as well as at
129 // some intermediate states where it is relevant (e.g. to determine how long
130 // it took for a session to become CONNECTED).
131 return (remoting.LogToServer.isEndOfSession(state) ||
132 (state == remoting.ClientSession.State.CONNECTED));
136 * Logs connection statistics.
137 * @param {Object.<string, number>} stats the connection statistics
138 * @param {remoting.ClientSession.Mode} mode
140 remoting.LogToServer.prototype.logStatistics = function(stats, mode) {
141 this.maybeExpireSessionId(mode);
142 // Store the statistics.
143 this.statsAccumulator_.add(stats);
144 // Send statistics to the server if they've been accumulating for at least
146 if (this.statsAccumulator_.getTimeSinceFirstValue() >=
147 remoting.LogToServer.CONNECTION_STATS_ACCUMULATE_TIME) {
148 this.logAccumulatedStatistics(mode);
153 * Moves connection statistics from the accumulator to the log server.
155 * If all the statistics are zero, then the accumulator is still emptied,
156 * but the statistics are not sent to the log server.
159 * @param {remoting.ClientSession.Mode} mode
161 remoting.LogToServer.prototype.logAccumulatedStatistics = function(mode) {
162 var entry = remoting.ServerLogEntry.makeStats(this.statsAccumulator_, mode);
164 entry.addHostFields();
165 entry.addChromeVersionField();
166 entry.addWebappVersionField();
167 entry.addSessionIdField(this.sessionId_);
170 this.statsAccumulator_.empty();
174 * Sends a log entry to the server.
177 * @param {remoting.ServerLogEntry} entry
179 remoting.LogToServer.prototype.log = function(entry) {
180 // Send the stanza to the debug log.
181 console.log('Enqueueing log entry:');
184 var stanza = '<cli:iq to="' + remoting.settings.DIRECTORY_BOT_JID + '" ' +
185 'type="set" xmlns:cli="jabber:client">' +
186 '<gr:log xmlns:gr="google:remoting">' +
190 this.signalStrategy_.sendMessage(stanza);
194 * Sets the session ID to a random string.
198 remoting.LogToServer.prototype.setSessionId = function() {
199 this.sessionId_ = remoting.LogToServer.generateSessionId();
200 this.sessionIdGenerationTime_ = new Date().getTime();
204 * Clears the session ID.
208 remoting.LogToServer.prototype.clearSessionId = function() {
209 this.sessionId_ = '';
210 this.sessionIdGenerationTime_ = 0;
214 * Sets a new session ID, if the current session ID has reached its maximum age.
216 * This method also logs the old and new session IDs to the server, in separate
220 * @param {remoting.ClientSession.Mode} mode
222 remoting.LogToServer.prototype.maybeExpireSessionId = function(mode) {
223 if ((this.sessionId_ != '') &&
224 (new Date().getTime() - this.sessionIdGenerationTime_ >=
225 remoting.LogToServer.MAX_SESSION_ID_AGE)) {
226 // Log the old session ID.
227 var entry = remoting.ServerLogEntry.makeSessionIdOld(this.sessionId_, mode);
229 // Generate a new session ID.
231 // Log the new session ID.
232 entry = remoting.ServerLogEntry.makeSessionIdNew(this.sessionId_, mode);
238 * Generates a string that can be used as a session ID.
241 * @return {string} a session ID
243 remoting.LogToServer.generateSessionId = function() {
245 for (var i = 0; i < remoting.LogToServer.SESSION_ID_LEN_; i++) {
247 Math.random() * remoting.LogToServer.SESSION_ID_ALPHABET_.length;
249 remoting.LogToServer.SESSION_ID_ALPHABET_.slice(index, index + 1));
251 return idArray.join('');