OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "google_apis/gcm/monitoring/gcm_stats_recorder.h" | 5 #include "google_apis/gcm/monitoring/gcm_stats_recorder.h" |
6 | 6 |
7 #include <deque> | 7 #include <deque> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
| 10 #include "base/format_macros.h" |
10 #include "base/logging.h" | 11 #include "base/logging.h" |
11 #include "base/metrics/histogram.h" | 12 #include "base/metrics/histogram.h" |
12 #include "base/strings/string_util.h" | 13 #include "base/strings/string_util.h" |
13 #include "base/strings/stringprintf.h" | 14 #include "base/strings/stringprintf.h" |
14 | 15 |
15 namespace gcm { | 16 namespace gcm { |
16 | 17 |
17 const uint32 MAX_LOGGED_ACTIVITY_COUNT = 100; | 18 const uint32 MAX_LOGGED_ACTIVITY_COUNT = 100; |
18 | 19 |
19 namespace { | 20 namespace { |
(...skipping 27 matching lines...) Expand all Loading... |
47 case gcm::MCSClient::NO_CONNECTION_ON_ZERO_TTL: | 48 case gcm::MCSClient::NO_CONNECTION_ON_ZERO_TTL: |
48 return "NO_CONNECTION_ON_ZERO_TTL"; | 49 return "NO_CONNECTION_ON_ZERO_TTL"; |
49 case gcm::MCSClient::TTL_EXCEEDED: | 50 case gcm::MCSClient::TTL_EXCEEDED: |
50 return "TTL_EXCEEDED"; | 51 return "TTL_EXCEEDED"; |
51 default: | 52 default: |
52 NOTREACHED(); | 53 NOTREACHED(); |
53 return "UNKNOWN"; | 54 return "UNKNOWN"; |
54 } | 55 } |
55 } | 56 } |
56 | 57 |
| 58 // Helper for getting string representation of the |
| 59 // ConnectionFactory::ConnectionResetReason enum. |
| 60 std::string GetConnectionResetReasonString( |
| 61 gcm::ConnectionFactory::ConnectionResetReason reason) { |
| 62 switch (reason) { |
| 63 case gcm::ConnectionFactory::LOGIN_FAILURE: |
| 64 return "LOGIN_FAILURE"; |
| 65 case gcm::ConnectionFactory::CLOSE_COMMAND: |
| 66 return "CLOSE_COMMAND"; |
| 67 case gcm::ConnectionFactory::HEARTBEAT_FAILURE: |
| 68 return "HEARTBEAT_FAILURE"; |
| 69 case gcm::ConnectionFactory::SOCKET_FAILURE: |
| 70 return "SOCKET_FAILURE"; |
| 71 case gcm::ConnectionFactory::NETWORK_CHANGE: |
| 72 return "NETWORK_CHANGE"; |
| 73 default: |
| 74 NOTREACHED(); |
| 75 return "UNKNOWN_REASON"; |
| 76 } |
| 77 } |
| 78 |
| 79 // Helper for getting string representation of the RegistrationRequest::Status |
| 80 // enum. |
| 81 std::string GetRegistrationStatusString( |
| 82 gcm::RegistrationRequest::Status status) { |
| 83 switch (status) { |
| 84 case gcm::RegistrationRequest::SUCCESS: |
| 85 return "SUCCESS"; |
| 86 case gcm::RegistrationRequest::INVALID_PARAMETERS: |
| 87 return "INVALID_PARAMETERS"; |
| 88 case gcm::RegistrationRequest::INVALID_SENDER: |
| 89 return "INVALID_SENDER"; |
| 90 case gcm::RegistrationRequest::AUTHENTICATION_FAILED: |
| 91 return "AUTHENTICATION_FAILED"; |
| 92 case gcm::RegistrationRequest::DEVICE_REGISTRATION_ERROR: |
| 93 return "DEVICE_REGISTRATION_ERROR"; |
| 94 case gcm::RegistrationRequest::UNKNOWN_ERROR: |
| 95 return "UNKNOWN_ERROR"; |
| 96 case gcm::RegistrationRequest::URL_FETCHING_FAILED: |
| 97 return "URL_FETCHING_FAILED"; |
| 98 case gcm::RegistrationRequest::HTTP_NOT_OK: |
| 99 return "HTTP_NOT_OK"; |
| 100 case gcm::RegistrationRequest::RESPONSE_PARSING_FAILED: |
| 101 return "RESPONSE_PARSING_FAILED"; |
| 102 case gcm::RegistrationRequest::REACHED_MAX_RETRIES: |
| 103 return "REACHED_MAX_RETRIES"; |
| 104 default: |
| 105 NOTREACHED(); |
| 106 return "UNKNOWN_STATUS"; |
| 107 } |
| 108 } |
| 109 |
| 110 // Helper for getting string representation of the RegistrationRequest::Status |
| 111 // enum. |
| 112 std::string GetUnregistrationStatusString( |
| 113 gcm::UnregistrationRequest::Status status) { |
| 114 switch (status) { |
| 115 case gcm::UnregistrationRequest::SUCCESS: |
| 116 return "SUCCESS"; |
| 117 case gcm::UnregistrationRequest::URL_FETCHING_FAILED: |
| 118 return "URL_FETCHING_FAILED"; |
| 119 case gcm::UnregistrationRequest::NO_RESPONSE_BODY: |
| 120 return "NO_RESPONSE_BODY"; |
| 121 case gcm::UnregistrationRequest::RESPONSE_PARSING_FAILED: |
| 122 return "RESPONSE_PARSING_FAILED"; |
| 123 case gcm::UnregistrationRequest::INCORRECT_APP_ID: |
| 124 return "INCORRECT_APP_ID"; |
| 125 case gcm::UnregistrationRequest::INVALID_PARAMETERS: |
| 126 return "INVALID_PARAMETERS"; |
| 127 case gcm::UnregistrationRequest::SERVICE_UNAVAILABLE: |
| 128 return "SERVICE_UNAVAILABLE"; |
| 129 case gcm::UnregistrationRequest::INTERNAL_SERVER_ERROR: |
| 130 return "INTERNAL_SERVER_ERROR"; |
| 131 case gcm::UnregistrationRequest::HTTP_NOT_OK: |
| 132 return "HTTP_NOT_OK"; |
| 133 case gcm::UnregistrationRequest::UNKNOWN_ERROR: |
| 134 return "UNKNOWN_ERROR"; |
| 135 default: |
| 136 NOTREACHED(); |
| 137 return "UNKNOWN_STATUS"; |
| 138 } |
| 139 } |
| 140 |
57 } // namespace | 141 } // namespace |
58 | 142 |
59 GCMStatsRecorder::Activity::Activity() | 143 GCMStatsRecorder::Activity::Activity() |
60 : time(base::Time::Now()) { | 144 : time(base::Time::Now()) { |
61 } | 145 } |
62 | 146 |
63 GCMStatsRecorder::Activity::~Activity() { | 147 GCMStatsRecorder::Activity::~Activity() { |
64 } | 148 } |
65 | 149 |
| 150 GCMStatsRecorder::ConnectionActivity::ConnectionActivity() { |
| 151 } |
| 152 |
| 153 GCMStatsRecorder::ConnectionActivity::~ConnectionActivity() { |
| 154 } |
| 155 |
| 156 GCMStatsRecorder::RegistrationActivity::RegistrationActivity() { |
| 157 } |
| 158 |
| 159 GCMStatsRecorder::RegistrationActivity::~RegistrationActivity() { |
| 160 } |
| 161 |
| 162 GCMStatsRecorder::ReceivingActivity::ReceivingActivity() |
| 163 : message_byte_size(0) { |
| 164 } |
| 165 |
| 166 GCMStatsRecorder::ReceivingActivity::~ReceivingActivity() { |
| 167 } |
| 168 |
66 GCMStatsRecorder::SendingActivity::SendingActivity() { | 169 GCMStatsRecorder::SendingActivity::SendingActivity() { |
67 } | 170 } |
68 | 171 |
69 GCMStatsRecorder::SendingActivity::~SendingActivity() { | 172 GCMStatsRecorder::SendingActivity::~SendingActivity() { |
70 } | 173 } |
71 | 174 |
| 175 GCMStatsRecorder::RecordedActivities::RecordedActivities() { |
| 176 } |
| 177 |
| 178 GCMStatsRecorder::RecordedActivities::~RecordedActivities() { |
| 179 } |
| 180 |
72 GCMStatsRecorder::GCMStatsRecorder() : is_recording_(false) { | 181 GCMStatsRecorder::GCMStatsRecorder() : is_recording_(false) { |
73 } | 182 } |
74 | 183 |
75 GCMStatsRecorder::~GCMStatsRecorder() { | 184 GCMStatsRecorder::~GCMStatsRecorder() { |
76 } | 185 } |
77 | 186 |
78 void GCMStatsRecorder::SetRecording(bool recording) { | 187 void GCMStatsRecorder::SetRecording(bool recording) { |
79 is_recording_ = recording; | 188 is_recording_ = recording; |
80 } | 189 } |
81 | 190 |
82 void GCMStatsRecorder::Clear() { | 191 void GCMStatsRecorder::Clear() { |
| 192 connection_activities_.clear(); |
| 193 registration_activities_.clear(); |
| 194 receiving_activities_.clear(); |
83 sending_activities_.clear(); | 195 sending_activities_.clear(); |
84 } | 196 } |
85 | 197 |
86 void GCMStatsRecorder::CollectSendingActivities( | 198 void GCMStatsRecorder::RecordConnection( |
87 std::vector<SendingActivity>* activities) const { | 199 const std::string& event, |
88 activities->insert(activities->begin(), | 200 const std::string& details) { |
89 sending_activities_.begin(), | 201 ConnectionActivity data; |
90 sending_activities_.end()); | 202 ConnectionActivity* inserted_data = InsertCircularBuffer( |
| 203 &connection_activities_, data); |
| 204 inserted_data->event = event; |
| 205 inserted_data->details = details; |
| 206 } |
| 207 |
| 208 void GCMStatsRecorder::RecordConnectionInitiated(const std::string& host) { |
| 209 if (!is_recording_) |
| 210 return; |
| 211 RecordConnection("Connection initiated", host); |
| 212 } |
| 213 |
| 214 void GCMStatsRecorder::RecordConnectionDelayedDueToBackoff(int64 delay_msec) { |
| 215 if (!is_recording_) |
| 216 return; |
| 217 RecordConnection("Connection backoff", |
| 218 base::StringPrintf("Delayed for %" PRId64 " msec", |
| 219 delay_msec)); |
| 220 } |
| 221 |
| 222 void GCMStatsRecorder::RecordConnectionSuccess() { |
| 223 if (!is_recording_) |
| 224 return; |
| 225 RecordConnection("Connection succeeded", std::string()); |
| 226 } |
| 227 |
| 228 void GCMStatsRecorder::RecordConnectionFailure(int network_error) { |
| 229 if (!is_recording_) |
| 230 return; |
| 231 RecordConnection("Connection failed", |
| 232 base::StringPrintf("With network error %d", network_error)); |
| 233 } |
| 234 |
| 235 void GCMStatsRecorder::RecordConnectionResetSignaled( |
| 236 ConnectionFactory::ConnectionResetReason reason) { |
| 237 if (!is_recording_) |
| 238 return; |
| 239 RecordConnection("Connection reset", |
| 240 GetConnectionResetReasonString(reason)); |
| 241 } |
| 242 |
| 243 void GCMStatsRecorder::RecordRegistration( |
| 244 const std::string& app_id, |
| 245 const std::string& sender_ids, |
| 246 const std::string& event, |
| 247 const std::string& details) { |
| 248 RegistrationActivity data; |
| 249 RegistrationActivity* inserted_data = InsertCircularBuffer( |
| 250 ®istration_activities_, data); |
| 251 inserted_data->app_id = app_id; |
| 252 inserted_data->sender_ids = sender_ids; |
| 253 inserted_data->event = event; |
| 254 inserted_data->details = details; |
| 255 } |
| 256 |
| 257 void GCMStatsRecorder::RecordRegistrationSent( |
| 258 const std::string& app_id, |
| 259 const std::string& sender_ids) { |
| 260 UMA_HISTOGRAM_COUNTS("GCM.RegistrationRequest", 1); |
| 261 if (!is_recording_) |
| 262 return; |
| 263 RecordRegistration(app_id, sender_ids, |
| 264 "Registration request sent", std::string()); |
| 265 } |
| 266 |
| 267 void GCMStatsRecorder::RecordRegistrationResponse( |
| 268 const std::string& app_id, |
| 269 const std::vector<std::string>& sender_ids, |
| 270 RegistrationRequest::Status status) { |
| 271 RecordRegistration(app_id, JoinString(sender_ids, ","), |
| 272 "Registration response received", |
| 273 GetRegistrationStatusString(status)); |
| 274 } |
| 275 |
| 276 void GCMStatsRecorder::RecordRegistrationRetryRequested( |
| 277 const std::string& app_id, |
| 278 const std::vector<std::string>& sender_ids, |
| 279 int retries_left) { |
| 280 if (!is_recording_) |
| 281 return; |
| 282 RecordRegistration(app_id, JoinString(sender_ids, ","), |
| 283 "Registration retry requested", |
| 284 base::StringPrintf("Retries left: %d", retries_left)); |
| 285 } |
| 286 |
| 287 void GCMStatsRecorder::RecordUnregistrationSent( |
| 288 const std::string& app_id) { |
| 289 UMA_HISTOGRAM_COUNTS("GCM.UnregistrationRequest", 1); |
| 290 if (!is_recording_) |
| 291 return; |
| 292 RecordRegistration(app_id, std::string(), "Unregistration request sent", |
| 293 std::string()); |
| 294 } |
| 295 |
| 296 void GCMStatsRecorder::RecordUnregistrationResponse( |
| 297 const std::string& app_id, |
| 298 UnregistrationRequest::Status status) { |
| 299 if (!is_recording_) |
| 300 return; |
| 301 RecordRegistration(app_id, |
| 302 std::string(), |
| 303 "Unregistration response received", |
| 304 GetUnregistrationStatusString(status)); |
| 305 } |
| 306 |
| 307 void GCMStatsRecorder::RecordUnregistrationRetryDelayed( |
| 308 const std::string& app_id, |
| 309 int64 delay_msec) { |
| 310 if (!is_recording_) |
| 311 return; |
| 312 RecordRegistration(app_id, |
| 313 std::string(), |
| 314 "Unregistration retry delayed", |
| 315 base::StringPrintf("Delayed for %" PRId64 " msec", |
| 316 delay_msec)); |
| 317 } |
| 318 |
| 319 void GCMStatsRecorder::RecordReceiving( |
| 320 const std::string& app_id, |
| 321 const std::string& from, |
| 322 int message_byte_size, |
| 323 const std::string& event, |
| 324 const std::string& details) { |
| 325 ReceivingActivity data; |
| 326 ReceivingActivity* inserted_data = InsertCircularBuffer( |
| 327 &receiving_activities_, data); |
| 328 inserted_data->app_id = app_id; |
| 329 inserted_data->from = from; |
| 330 inserted_data->message_byte_size = message_byte_size; |
| 331 inserted_data->event = event; |
| 332 inserted_data->details = details; |
| 333 } |
| 334 |
| 335 void GCMStatsRecorder::RecordDataMessageRecieved( |
| 336 const std::string& app_id, |
| 337 const std::string& from, |
| 338 int message_byte_size, |
| 339 bool to_registered_app, |
| 340 ReceivedMessageType message_type) { |
| 341 if (to_registered_app) |
| 342 UMA_HISTOGRAM_COUNTS("GCM.DataMessageReceived", 1); |
| 343 if (!is_recording_) |
| 344 return; |
| 345 if (!to_registered_app) { |
| 346 RecordReceiving(app_id, from, message_byte_size, "Data msg received", |
| 347 to_registered_app ? std::string() : |
| 348 "No such registered app found"); |
| 349 } else { |
| 350 switch(message_type) { |
| 351 case GCMStatsRecorder::DATA_MESSAGE: |
| 352 RecordReceiving(app_id, from, message_byte_size, "Data msg received", |
| 353 std::string()); |
| 354 break; |
| 355 case GCMStatsRecorder::DELETED_MESSAGES: |
| 356 RecordReceiving(app_id, from, message_byte_size, "Data msg received", |
| 357 "Message has been deleted on server"); |
| 358 break; |
| 359 default: |
| 360 NOTREACHED(); |
| 361 } |
| 362 } |
| 363 } |
| 364 |
| 365 void GCMStatsRecorder::CollectActivities( |
| 366 RecordedActivities* recorder_activities) const { |
| 367 recorder_activities->connection_activities.insert( |
| 368 recorder_activities->connection_activities.begin(), |
| 369 connection_activities_.begin(), |
| 370 connection_activities_.end()); |
| 371 recorder_activities->registration_activities.insert( |
| 372 recorder_activities->registration_activities.begin(), |
| 373 registration_activities_.begin(), |
| 374 registration_activities_.end()); |
| 375 recorder_activities->receiving_activities.insert( |
| 376 recorder_activities->receiving_activities.begin(), |
| 377 receiving_activities_.begin(), |
| 378 receiving_activities_.end()); |
| 379 recorder_activities->sending_activities.insert( |
| 380 recorder_activities->sending_activities.begin(), |
| 381 sending_activities_.begin(), |
| 382 sending_activities_.end()); |
91 } | 383 } |
92 | 384 |
93 void GCMStatsRecorder::RecordSending(const std::string& app_id, | 385 void GCMStatsRecorder::RecordSending(const std::string& app_id, |
94 const std::string& receiver_id, | 386 const std::string& receiver_id, |
95 const std::string& message_id, | 387 const std::string& message_id, |
96 const std::string& event, | 388 const std::string& event, |
97 const std::string& details) { | 389 const std::string& details) { |
98 SendingActivity data; | 390 SendingActivity data; |
99 SendingActivity* inserted_data = InsertCircularBuffer( | 391 SendingActivity* inserted_data = InsertCircularBuffer( |
100 &sending_activities_, data); | 392 &sending_activities_, data); |
101 inserted_data->app_id = app_id; | 393 inserted_data->app_id = app_id; |
102 inserted_data->receiver_id = receiver_id; | 394 inserted_data->receiver_id = receiver_id; |
103 inserted_data->message_id = message_id; | 395 inserted_data->message_id = message_id; |
104 inserted_data->event = event; | 396 inserted_data->event = event; |
105 inserted_data->details = details; | 397 inserted_data->details = details; |
106 } | 398 } |
107 | 399 |
108 void GCMStatsRecorder::RecordDataSentToWire( | 400 void GCMStatsRecorder::RecordDataSentToWire( |
109 const std::string& app_id, | 401 const std::string& app_id, |
110 const std::string& receiver_id, | 402 const std::string& receiver_id, |
111 const std::string& message_id, | 403 const std::string& message_id, |
112 int queued) { | 404 int queued) { |
113 if (is_recording_) { | 405 if (!is_recording_) |
114 RecordSending(app_id, receiver_id, message_id, "Data msg sent to wire", | 406 return; |
115 base::StringPrintf("Msg queued for %d seconds", queued)); | 407 RecordSending(app_id, receiver_id, message_id, "Data msg sent to wire", |
116 } | 408 base::StringPrintf("Msg queued for %d seconds", queued)); |
117 } | 409 } |
118 | 410 |
119 void GCMStatsRecorder::RecordNotifySendStatus( | 411 void GCMStatsRecorder::RecordNotifySendStatus( |
120 const std::string& app_id, | 412 const std::string& app_id, |
121 const std::string& receiver_id, | 413 const std::string& receiver_id, |
122 const std::string& message_id, | 414 const std::string& message_id, |
123 gcm::MCSClient::MessageSendStatus status, | 415 gcm::MCSClient::MessageSendStatus status, |
124 int byte_size, | 416 int byte_size, |
125 int ttl) { | 417 int ttl) { |
126 UMA_HISTOGRAM_ENUMERATION("GCM.SendMessageStatus", status, | 418 UMA_HISTOGRAM_ENUMERATION("GCM.SendMessageStatus", status, |
127 gcm::MCSClient::SEND_STATUS_COUNT); | 419 gcm::MCSClient::SEND_STATUS_COUNT); |
128 if (is_recording_) { | 420 if (!is_recording_) |
129 RecordSending( | 421 return; |
130 app_id, | 422 RecordSending( |
131 receiver_id, | 423 app_id, |
132 message_id, | 424 receiver_id, |
133 base::StringPrintf("SEND status: %s", | 425 message_id, |
134 GetMessageSendStatusString(status).c_str()), | 426 base::StringPrintf("SEND status: %s", |
135 base::StringPrintf("Msg size: %d bytes, TTL: %d", byte_size, ttl)); | 427 GetMessageSendStatusString(status).c_str()), |
136 } | 428 base::StringPrintf("Msg size: %d bytes, TTL: %d", byte_size, ttl)); |
137 } | 429 } |
138 | 430 |
139 void GCMStatsRecorder::RecordIncomingSendError( | 431 void GCMStatsRecorder::RecordIncomingSendError( |
140 const std::string& app_id, | 432 const std::string& app_id, |
141 const std::string& receiver_id, | 433 const std::string& receiver_id, |
142 const std::string& message_id) { | 434 const std::string& message_id) { |
143 UMA_HISTOGRAM_COUNTS("GCM.IncomingSendErrors", 1); | 435 UMA_HISTOGRAM_COUNTS("GCM.IncomingSendErrors", 1); |
144 if (is_recording_) { | 436 if (!is_recording_) |
145 RecordSending(app_id, receiver_id, message_id, "Received 'send error' msg", | 437 return; |
146 std::string()); | 438 RecordSending(app_id, receiver_id, message_id, "Received 'send error' msg", |
147 } | 439 std::string()); |
148 } | 440 } |
149 | 441 |
150 } // namespace gcm | 442 } // namespace gcm |
OLD | NEW |