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
|| {};
18 remoting
.LogToServer = function() {
19 /** @type Array.<string> */
20 this.pendingEntries
= [];
21 /** @type {remoting.StatsAccumulator} */
22 this.statsAccumulator
= new remoting
.StatsAccumulator();
26 this.sessionIdGenerationTime
= 0;
28 this.sessionStartTime
= 0;
31 // Constants used for generating a session ID.
33 remoting
.LogToServer
.SESSION_ID_ALPHABET_
=
34 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
36 remoting
.LogToServer
.SESSION_ID_LEN_
= 20;
38 // The maximum age of a session ID, in milliseconds.
39 remoting
.LogToServer
.MAX_SESSION_ID_AGE
= 24 * 60 * 60 * 1000;
41 // The time over which to accumulate connection statistics before logging them
42 // to the server, in milliseconds.
43 remoting
.LogToServer
.CONNECTION_STATS_ACCUMULATE_TIME
= 60 * 1000;
46 * Logs a client session state change.
48 * @param {remoting.ClientSession.State} state
49 * @param {remoting.ClientSession.ConnectionError} connectionError
50 * @param {remoting.ClientSession.Mode} mode
52 remoting
.LogToServer
.prototype.logClientSessionStateChange
=
53 function(state
, connectionError
, mode
) {
54 this.maybeExpireSessionId(mode
);
55 // Maybe set the session ID and start time.
56 if (remoting
.LogToServer
.isStartOfSession(state
)) {
57 if (this.sessionId
== '') {
60 if (this.sessionStartTime
== 0) {
61 this.sessionStartTime
= new Date().getTime();
64 // Log the session state change.
65 var entry
= remoting
.ServerLogEntry
.makeClientSessionStateChange(
66 state
, connectionError
, mode
);
67 entry
.addHostFields();
68 entry
.addChromeVersionField();
69 entry
.addWebappVersionField();
70 entry
.addSessionIdField(this.sessionId
);
71 // Maybe clear the session start time, and log the session duration.
72 if (remoting
.LogToServer
.isEndOfSession(state
) &&
73 (this.sessionStartTime
!= 0)) {
74 entry
.addSessionDurationField(
75 (new Date().getTime() - this.sessionStartTime
) / 1000.0);
76 this.sessionStartTime
= 0;
79 // Don't accumulate connection statistics across state changes.
80 this.logAccumulatedStatistics(mode
);
81 this.statsAccumulator
.empty();
82 // Maybe clear the session ID.
83 if (remoting
.LogToServer
.isEndOfSession(state
)) {
84 this.clearSessionId();
89 * Whether a session state is one of the states that occurs at the start of
93 * @param {remoting.ClientSession.State} state
96 remoting
.LogToServer
.isStartOfSession = function(state
) {
97 return ((state
== remoting
.ClientSession
.State
.CONNECTING
) ||
98 (state
== remoting
.ClientSession
.State
.INITIALIZING
) ||
99 (state
== remoting
.ClientSession
.State
.CONNECTED
));
103 * Whether a session state is one of the states that occurs at the end of
107 * @param {remoting.ClientSession.State} state
110 remoting
.LogToServer
.isEndOfSession = function(state
) {
111 return ((state
== remoting
.ClientSession
.State
.CLOSED
) ||
112 (state
== remoting
.ClientSession
.State
.FAILED
));
116 * Logs connection statistics.
117 * @param {Object.<string, number>} stats the connection statistics
118 * @param {remoting.ClientSession.Mode} mode
120 remoting
.LogToServer
.prototype.logStatistics = function(stats
, mode
) {
121 this.maybeExpireSessionId(mode
);
122 // Store the statistics.
123 this.statsAccumulator
.add(stats
);
124 // Send statistics to the server if they've been accumulating for at least
126 if (this.statsAccumulator
.getTimeSinceFirstValue() >=
127 remoting
.LogToServer
.CONNECTION_STATS_ACCUMULATE_TIME
) {
128 this.logAccumulatedStatistics(mode
);
133 * Moves connection statistics from the accumulator to the log server.
135 * If all the statistics are zero, then the accumulator is still emptied,
136 * but the statistics are not sent to the log server.
139 * @param {remoting.ClientSession.Mode} mode
141 remoting
.LogToServer
.prototype.logAccumulatedStatistics = function(mode
) {
142 var entry
= remoting
.ServerLogEntry
.makeStats(this.statsAccumulator
, mode
);
144 entry
.addHostFields();
145 entry
.addChromeVersionField();
146 entry
.addWebappVersionField();
147 entry
.addSessionIdField(this.sessionId
);
150 this.statsAccumulator
.empty();
154 * Sends a log entry to the server.
157 * @param {remoting.ServerLogEntry} entry
159 remoting
.LogToServer
.prototype.log = function(entry
) {
160 // Send the stanza to the debug log.
161 console
.log('Enqueueing log entry:');
163 // Store a stanza for the entry.
164 this.pendingEntries
.push(entry
.toStanza());
165 // Stop if there's no connection to the server.
169 // Send all pending entries to the server.
170 console
.log('Sending ' + this.pendingEntries
.length
+ ' log ' +
171 ((this.pendingEntries
.length
== 1) ? 'entry' : 'entries') +
173 var stanza
= '<cli:iq to="remoting@bot.talk.google.com" type="set" ' +
174 'xmlns:cli="jabber:client"><gr:log xmlns:gr="google:remoting">';
175 while (this.pendingEntries
.length
> 0) {
176 stanza
+= /** @type string */ this.pendingEntries
.shift();
178 stanza
+= '</gr:log></cli:iq>';
179 remoting
.wcs
.sendIq(stanza
);
183 * Sets the session ID to a random string.
187 remoting
.LogToServer
.prototype.setSessionId = function() {
188 this.sessionId
= remoting
.LogToServer
.generateSessionId();
189 this.sessionIdGenerationTime
= new Date().getTime();
193 * Clears the session ID.
197 remoting
.LogToServer
.prototype.clearSessionId = function() {
199 this.sessionIdGenerationTime
= 0;
203 * Sets a new session ID, if the current session ID has reached its maximum age.
205 * This method also logs the old and new session IDs to the server, in separate
209 * @param {remoting.ClientSession.Mode} mode
211 remoting
.LogToServer
.prototype.maybeExpireSessionId = function(mode
) {
212 if ((this.sessionId
!= '') &&
213 (new Date().getTime() - this.sessionIdGenerationTime
>=
214 remoting
.LogToServer
.MAX_SESSION_ID_AGE
)) {
215 // Log the old session ID.
216 var entry
= remoting
.ServerLogEntry
.makeSessionIdOld(this.sessionId
, mode
);
218 // Generate a new session ID.
220 // Log the new session ID.
221 entry
= remoting
.ServerLogEntry
.makeSessionIdNew(this.sessionId
, mode
);
227 * Generates a string that can be used as a session ID.
230 * @return {string} a session ID
232 remoting
.LogToServer
.generateSessionId = function() {
234 for (var i
= 0; i
< remoting
.LogToServer
.SESSION_ID_LEN_
; i
++) {
236 Math
.random() * remoting
.LogToServer
.SESSION_ID_ALPHABET_
.length
;
238 remoting
.LogToServer
.SESSION_ID_ALPHABET_
.slice(index
, index
+ 1));
240 return idArray
.join('');