OLD | NEW |
(Empty) | |
| 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 |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "google_apis/gcm/monitoring/gcm_stats_recorder.h" |
| 6 |
| 7 #include <deque> |
| 8 #include <vector> |
| 9 |
| 10 #include "base/logging.h" |
| 11 #include "base/metrics/histogram.h" |
| 12 #include "base/strings/string_util.h" |
| 13 #include "base/strings/stringprintf.h" |
| 14 |
| 15 namespace gcm { |
| 16 |
| 17 const uint32 MAX_LOGGED_ACTIVITY_COUNT = 100; |
| 18 |
| 19 namespace { |
| 20 |
| 21 // Insert an itme to the front of deque while maintaining the size of the deque. |
| 22 // Overflow item is discarded. |
| 23 template <typename T> |
| 24 T* InsertCircularBuffer(std::deque<T>* q, const T& item) { |
| 25 DCHECK(q); |
| 26 q->push_front(item); |
| 27 if (q->size() > MAX_LOGGED_ACTIVITY_COUNT) { |
| 28 q->pop_back(); |
| 29 } |
| 30 return &q->front(); |
| 31 } |
| 32 |
| 33 // Helper for getting string representation of the MessageSendStatus enum. |
| 34 std::string GetMessageSendStatusString( |
| 35 gcm::MCSClient::MessageSendStatus status) { |
| 36 switch (status) { |
| 37 case gcm::MCSClient::QUEUED: |
| 38 return "QUEUED"; |
| 39 case gcm::MCSClient::SENT: |
| 40 return "SENT"; |
| 41 case gcm::MCSClient::QUEUE_SIZE_LIMIT_REACHED: |
| 42 return "QUEUE_SIZE_LIMIT_REACHED"; |
| 43 case gcm::MCSClient::APP_QUEUE_SIZE_LIMIT_REACHED: |
| 44 return "APP_QUEUE_SIZE_LIMIT_REACHED"; |
| 45 case gcm::MCSClient::MESSAGE_TOO_LARGE: |
| 46 return "MESSAGE_TOO_LARGE"; |
| 47 case gcm::MCSClient::NO_CONNECTION_ON_ZERO_TTL: |
| 48 return "NO_CONNECTION_ON_ZERO_TTL"; |
| 49 case gcm::MCSClient::TTL_EXCEEDED: |
| 50 return "TTL_EXCEEDED"; |
| 51 default: |
| 52 NOTREACHED(); |
| 53 return "UNKNOWN"; |
| 54 } |
| 55 } |
| 56 |
| 57 } // namespace |
| 58 |
| 59 GCMStatsRecorder::Activity::Activity() |
| 60 : time(base::Time::Now()) { |
| 61 } |
| 62 |
| 63 GCMStatsRecorder::Activity::~Activity() { |
| 64 } |
| 65 |
| 66 GCMStatsRecorder::SendingActivity::SendingActivity() { |
| 67 } |
| 68 |
| 69 GCMStatsRecorder::SendingActivity::~SendingActivity() { |
| 70 } |
| 71 |
| 72 GCMStatsRecorder::GCMStatsRecorder() : is_recording_(false) { |
| 73 } |
| 74 |
| 75 GCMStatsRecorder::~GCMStatsRecorder() { |
| 76 } |
| 77 |
| 78 void GCMStatsRecorder::SetRecording(bool recording) { |
| 79 is_recording_ = recording; |
| 80 } |
| 81 |
| 82 void GCMStatsRecorder::Clear() { |
| 83 sending_activities_.clear(); |
| 84 } |
| 85 |
| 86 void GCMStatsRecorder::CollectSendingActivities( |
| 87 std::vector<SendingActivity>* activities) const { |
| 88 activities->insert(activities->begin(), |
| 89 sending_activities_.begin(), |
| 90 sending_activities_.end()); |
| 91 } |
| 92 |
| 93 void GCMStatsRecorder::RecordSending(const std::string& app_id, |
| 94 const std::string& receiver_id, |
| 95 const std::string& message_id, |
| 96 const std::string& event, |
| 97 const std::string& details) { |
| 98 SendingActivity data; |
| 99 SendingActivity* inserted_data = InsertCircularBuffer( |
| 100 &sending_activities_, data); |
| 101 inserted_data->app_id = app_id; |
| 102 inserted_data->receiver_id = receiver_id; |
| 103 inserted_data->message_id = message_id; |
| 104 inserted_data->event = event; |
| 105 inserted_data->details = details; |
| 106 } |
| 107 |
| 108 void GCMStatsRecorder::RecordDataSentToWire( |
| 109 const std::string& app_id, |
| 110 const std::string& receiver_id, |
| 111 const std::string& message_id, |
| 112 int queued) { |
| 113 if (is_recording_) { |
| 114 RecordSending(app_id, receiver_id, message_id, "Data msg sent to wire", |
| 115 base::StringPrintf("Msg queued for %d seconds", queued)); |
| 116 } |
| 117 } |
| 118 |
| 119 void GCMStatsRecorder::RecordNotifySendStatus( |
| 120 const std::string& app_id, |
| 121 const std::string& receiver_id, |
| 122 const std::string& message_id, |
| 123 gcm::MCSClient::MessageSendStatus status, |
| 124 int byte_size, |
| 125 int ttl) { |
| 126 UMA_HISTOGRAM_ENUMERATION("GCM.SendMessageStatus", status, |
| 127 gcm::MCSClient::SEND_STATUS_COUNT); |
| 128 if (is_recording_) { |
| 129 RecordSending( |
| 130 app_id, |
| 131 receiver_id, |
| 132 message_id, |
| 133 base::StringPrintf("SEND status: %s", |
| 134 GetMessageSendStatusString(status).c_str()), |
| 135 base::StringPrintf("Msg size: %d bytes, TTL: %d", byte_size, ttl)); |
| 136 } |
| 137 } |
| 138 |
| 139 void GCMStatsRecorder::RecordIncomingSendError( |
| 140 const std::string& app_id, |
| 141 const std::string& receiver_id, |
| 142 const std::string& message_id) { |
| 143 UMA_HISTOGRAM_COUNTS("GCM.IncomingSendErrors", 1); |
| 144 if (is_recording_) { |
| 145 RecordSending(app_id, receiver_id, message_id, "Received 'send error' msg", |
| 146 std::string()); |
| 147 } |
| 148 } |
| 149 |
| 150 } // namespace gcm |
OLD | NEW |