OLD | NEW |
| (Empty) |
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. | |
4 | |
5 /** | |
6 * @fileoverview | |
7 * Module for sending log entries to the server. | |
8 */ | |
9 | |
10 'use strict'; | |
11 | |
12 /** @suppress {duplicate} */ | |
13 var remoting = remoting || {}; | |
14 | |
15 /** | |
16 * @param {remoting.SignalStrategy} signalStrategy Signal strategy. | |
17 * @constructor | |
18 */ | |
19 remoting.LogToServer = function(signalStrategy) { | |
20 /** @private */ | |
21 this.statsAccumulator_ = new remoting.StatsAccumulator(); | |
22 /** @private */ | |
23 this.sessionId_ = ''; | |
24 /** @private */ | |
25 this.sessionIdGenerationTime_ = 0; | |
26 /** @private */ | |
27 this.sessionStartTime_ = new Date().getTime(); | |
28 /** @private */ | |
29 this.signalStrategy_ = signalStrategy; | |
30 /** @private {string} */ | |
31 this.connectionType_ = ''; | |
32 /** @private */ | |
33 this.authTotalTime_ = 0; | |
34 /** @private {string} */ | |
35 this.hostVersion_ = ''; | |
36 /** @private */ | |
37 this.logEntryMode_ = remoting.ServerLogEntry.VALUE_MODE_UNKNOWN; | |
38 | |
39 this.setSessionId_(); | |
40 signalStrategy.sendConnectionSetupResults(this); | |
41 }; | |
42 | |
43 // Constants used for generating a session ID. | |
44 /** @private */ | |
45 remoting.LogToServer.SESSION_ID_ALPHABET_ = | |
46 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'; | |
47 /** @private */ | |
48 remoting.LogToServer.SESSION_ID_LEN_ = 20; | |
49 | |
50 // The maximum age of a session ID, in milliseconds. | |
51 remoting.LogToServer.MAX_SESSION_ID_AGE = 24 * 60 * 60 * 1000; | |
52 | |
53 // The time over which to accumulate connection statistics before logging them | |
54 // to the server, in milliseconds. | |
55 remoting.LogToServer.CONNECTION_STATS_ACCUMULATE_TIME = 60 * 1000; | |
56 | |
57 /** | |
58 * Logs a client session state change. | |
59 * | |
60 * @param {remoting.ClientSession.State} state | |
61 * @param {!remoting.Error} connectionError | |
62 */ | |
63 remoting.LogToServer.prototype.logClientSessionStateChange = | |
64 function(state, connectionError) { | |
65 this.maybeExpireSessionId_(); | |
66 // Log the session state change. | |
67 var entry = remoting.ServerLogEntry.makeClientSessionStateChange( | |
68 state, connectionError, this.logEntryMode_); | |
69 entry.addClientOSFields(); | |
70 entry.addChromeVersionField(); | |
71 entry.addWebappVersionField(); | |
72 entry.addSessionIdField(this.sessionId_); | |
73 this.log_(entry); | |
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_(); | |
80 } | |
81 }; | |
82 | |
83 /** | |
84 * Set the connection type (direct, stun relay). | |
85 * | |
86 * @param {string} connectionType | |
87 */ | |
88 remoting.LogToServer.prototype.setConnectionType = function(connectionType) { | |
89 this.connectionType_ = connectionType; | |
90 }; | |
91 | |
92 /** | |
93 * @param {string} mode String indicating the connection mode. This should be | |
94 * one of the remoting.ServerLogEntry.VALUE_MODE_* values. | |
95 */ | |
96 remoting.LogToServer.prototype.setLogEntryMode = function(mode) { | |
97 this.logEntryMode_ = mode; | |
98 } | |
99 | |
100 /** | |
101 * @param {remoting.SignalStrategy.Type} strategyType | |
102 * @param {remoting.FallbackSignalStrategy.Progress} progress | |
103 */ | |
104 remoting.LogToServer.prototype.logSignalStrategyProgress = | |
105 function(strategyType, progress) { | |
106 this.maybeExpireSessionId_(); | |
107 var entry = remoting.ServerLogEntry.makeSignalStrategyProgress( | |
108 this.sessionId_, strategyType, progress); | |
109 this.log_(entry); | |
110 }; | |
111 | |
112 /** | |
113 * Whether a session state is one of the states that occurs at the start of | |
114 * a session. | |
115 * | |
116 * @private | |
117 * @param {remoting.ClientSession.State} state | |
118 * @return {boolean} | |
119 */ | |
120 remoting.LogToServer.isStartOfSession_ = function(state) { | |
121 return ((state == remoting.ClientSession.State.CONNECTING) || | |
122 (state == remoting.ClientSession.State.INITIALIZING) || | |
123 (state == remoting.ClientSession.State.AUTHENTICATED) || | |
124 (state == remoting.ClientSession.State.CONNECTED)); | |
125 }; | |
126 | |
127 /** | |
128 * Whether a session state is one of the states that occurs at the end of | |
129 * a session. | |
130 * | |
131 * @private | |
132 * @param {remoting.ClientSession.State} state | |
133 * @return {boolean} | |
134 */ | |
135 remoting.LogToServer.isEndOfSession_ = function(state) { | |
136 return ((state == remoting.ClientSession.State.CLOSED) || | |
137 (state == remoting.ClientSession.State.FAILED) || | |
138 (state == remoting.ClientSession.State.CONNECTION_DROPPED) || | |
139 (state == remoting.ClientSession.State.CONNECTION_CANCELED)); | |
140 }; | |
141 | |
142 | |
143 /** | |
144 * Logs connection statistics. | |
145 * @param {Object<string, number>} stats The connection statistics | |
146 */ | |
147 remoting.LogToServer.prototype.logStatistics = function(stats) { | |
148 this.maybeExpireSessionId_(); | |
149 // Store the statistics. | |
150 this.statsAccumulator_.add(stats); | |
151 // Send statistics to the server if they've been accumulating for at least | |
152 // 60 seconds. | |
153 if (this.statsAccumulator_.getTimeSinceFirstValue() >= | |
154 remoting.LogToServer.CONNECTION_STATS_ACCUMULATE_TIME) { | |
155 this.logAccumulatedStatistics_(); | |
156 } | |
157 }; | |
158 | |
159 /** | |
160 * Moves connection statistics from the accumulator to the log server. | |
161 * | |
162 * If all the statistics are zero, then the accumulator is still emptied, | |
163 * but the statistics are not sent to the log server. | |
164 * | |
165 * @private | |
166 */ | |
167 remoting.LogToServer.prototype.logAccumulatedStatistics_ = function() { | |
168 var entry = remoting.ServerLogEntry.makeStats(this.statsAccumulator_, | |
169 this.connectionType_, | |
170 this.logEntryMode_); | |
171 if (entry) { | |
172 entry.addClientOSFields(); | |
173 entry.addChromeVersionField(); | |
174 entry.addWebappVersionField(); | |
175 entry.addSessionIdField(this.sessionId_); | |
176 this.log_(entry); | |
177 } | |
178 this.statsAccumulator_.empty(); | |
179 }; | |
180 | |
181 /** | |
182 * Sends a log entry to the server. | |
183 * | |
184 * @private | |
185 * @param {remoting.ServerLogEntry} entry | |
186 */ | |
187 remoting.LogToServer.prototype.log_ = function(entry) { | |
188 // Log the time taken to get to this point from the time this session started. | |
189 // Exclude time taken for authorization. | |
190 var sessionDurationInSeconds = | |
191 (new Date().getTime() - this.sessionStartTime_ - | |
192 this.authTotalTime_) / 1000.0; | |
193 entry.addSessionDuration(sessionDurationInSeconds); | |
194 entry.addApplicationId(); | |
195 // The host-version will be blank for logs before a session has been created. | |
196 // For example, the signal-strategy log-entries won't have host version info. | |
197 entry.addHostVersion(this.hostVersion_); | |
198 | |
199 // Send the stanza to the debug log. | |
200 console.log('Enqueueing log entry:'); | |
201 entry.toDebugLog(1); | |
202 | |
203 var stanza = '<cli:iq to="' + remoting.settings.DIRECTORY_BOT_JID + '" ' + | |
204 'type="set" xmlns:cli="jabber:client">' + | |
205 '<gr:log xmlns:gr="google:remoting">' + | |
206 entry.toStanza() + | |
207 '</gr:log>' + | |
208 '</cli:iq>'; | |
209 this.signalStrategy_.sendMessage(stanza); | |
210 }; | |
211 | |
212 /** | |
213 * Sets the session ID to a random string. | |
214 * | |
215 * @private | |
216 */ | |
217 remoting.LogToServer.prototype.setSessionId_ = function() { | |
218 this.sessionId_ = remoting.LogToServer.generateSessionId_(); | |
219 this.sessionIdGenerationTime_ = new Date().getTime(); | |
220 }; | |
221 | |
222 /** | |
223 * Clears the session ID. | |
224 * | |
225 * @private | |
226 */ | |
227 remoting.LogToServer.prototype.clearSessionId_ = function() { | |
228 this.sessionId_ = ''; | |
229 this.sessionIdGenerationTime_ = 0; | |
230 }; | |
231 | |
232 /** | |
233 * Sets a new session ID, if the current session ID has reached its maximum age. | |
234 * | |
235 * This method also logs the old and new session IDs to the server, in separate | |
236 * log entries. | |
237 * | |
238 * @private | |
239 */ | |
240 remoting.LogToServer.prototype.maybeExpireSessionId_ = function() { | |
241 if ((this.sessionId_ != '') && | |
242 (new Date().getTime() - this.sessionIdGenerationTime_ >= | |
243 remoting.LogToServer.MAX_SESSION_ID_AGE)) { | |
244 // Log the old session ID. | |
245 var entry = remoting.ServerLogEntry.makeSessionIdOld(this.sessionId_, | |
246 this.logEntryMode_); | |
247 this.log_(entry); | |
248 // Generate a new session ID. | |
249 this.setSessionId_(); | |
250 // Log the new session ID. | |
251 entry = remoting.ServerLogEntry.makeSessionIdNew(this.sessionId_, | |
252 this.logEntryMode_); | |
253 this.log_(entry); | |
254 } | |
255 }; | |
256 | |
257 /** | |
258 * Generates a string that can be used as a session ID. | |
259 * | |
260 * @private | |
261 * @return {string} a session ID | |
262 */ | |
263 remoting.LogToServer.generateSessionId_ = function() { | |
264 var idArray = []; | |
265 for (var i = 0; i < remoting.LogToServer.SESSION_ID_LEN_; i++) { | |
266 var index = | |
267 Math.random() * remoting.LogToServer.SESSION_ID_ALPHABET_.length; | |
268 idArray.push( | |
269 remoting.LogToServer.SESSION_ID_ALPHABET_.slice(index, index + 1)); | |
270 } | |
271 return idArray.join(''); | |
272 }; | |
273 | |
274 /** | |
275 * @param {number} totalTime The value of time taken to complete authorization. | |
276 * @return {void} Nothing. | |
277 */ | |
278 remoting.LogToServer.prototype.setAuthTotalTime = function(totalTime) { | |
279 this.authTotalTime_ = totalTime; | |
280 }; | |
281 | |
282 /** | |
283 * @param {string} hostVersion Version of the host for current session. | |
284 * @return {void} Nothing. | |
285 */ | |
286 remoting.LogToServer.prototype.setHostVersion = function(hostVersion) { | |
287 this.hostVersion_ = hostVersion; | |
288 }; | |
289 | |
OLD | NEW |