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.
5 #include "sync/engine/traffic_recorder.h"
7 #include "base/json/json_writer.h"
8 #include "base/logging.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/values.h"
11 #include "sync/protocol/proto_value_conversions.h"
12 #include "sync/protocol/sync.pb.h"
13 #include "sync/sessions/sync_session.h"
14 #include "sync/util/time.h"
18 // Return current time.
19 base::Time
TrafficRecorder::GetTime() {
20 return base::Time::Now();
23 TrafficRecorder::TrafficRecord::TrafficRecord(const std::string
& message
,
24 TrafficMessageType message_type
,
28 message_type(message_type
),
33 TrafficRecorder::TrafficRecord::TrafficRecord()
34 : message_type(UNKNOWN_MESSAGE_TYPE
),
38 TrafficRecorder::TrafficRecord::~TrafficRecord() {
41 TrafficRecorder::TrafficRecorder(unsigned int max_messages
,
42 unsigned int max_message_size
)
43 : max_messages_(max_messages
),
44 max_message_size_(max_message_size
) {
47 TrafficRecorder::~TrafficRecorder() {
51 const char* GetMessageTypeString(TrafficRecorder::TrafficMessageType type
) {
53 case TrafficRecorder::CLIENT_TO_SERVER_MESSAGE
:
55 case TrafficRecorder::CLIENT_TO_SERVER_RESPONSE
:
64 base::DictionaryValue
* TrafficRecorder::TrafficRecord::ToValue() const {
65 scoped_ptr
<base::DictionaryValue
> value
;
67 value
.reset(new base::DictionaryValue());
68 value
->SetString("message_type",
69 GetMessageTypeString(message_type
));
70 value
->SetBoolean("truncated", true);
71 } else if (message_type
== TrafficRecorder::CLIENT_TO_SERVER_MESSAGE
) {
72 sync_pb::ClientToServerMessage message_proto
;
73 if (message_proto
.ParseFromString(message
))
75 ClientToServerMessageToValue(message_proto
,
76 false /* include_specifics */));
77 } else if (message_type
== TrafficRecorder::CLIENT_TO_SERVER_RESPONSE
) {
78 sync_pb::ClientToServerResponse message_proto
;
79 if (message_proto
.ParseFromString(message
))
81 ClientToServerResponseToValue(message_proto
,
82 false /* include_specifics */));
87 value
->SetString("timestamp", GetTimeDebugString(timestamp
));
89 return value
.release();
93 base::ListValue
* TrafficRecorder::ToValue() const {
94 scoped_ptr
<base::ListValue
> value(new base::ListValue());
95 std::deque
<TrafficRecord
>::const_iterator it
;
96 for (it
= records_
.begin(); it
!= records_
.end(); ++it
) {
97 const TrafficRecord
& record
= *it
;
98 value
->Append(record
.ToValue());
101 return value
.release();
105 void TrafficRecorder::AddTrafficToQueue(TrafficRecord
* record
) {
106 records_
.resize(records_
.size() + 1);
107 std::swap(records_
.back(), *record
);
109 // We might have more records than our limit.
110 // Maintain the size invariant by deleting items.
111 while (records_
.size() > max_messages_
) {
112 records_
.pop_front();
116 void TrafficRecorder::StoreProtoInQueue(
117 const ::google::protobuf::MessageLite
& msg
,
118 TrafficMessageType type
) {
119 bool truncated
= false;
121 if (static_cast<unsigned int>(msg
.ByteSize()) >= max_message_size_
) {
122 // TODO(lipalani): Trim the specifics to fit in size.
125 msg
.SerializeToString(&message
);
128 TrafficRecord
record(message
, type
, truncated
, GetTime());
129 AddTrafficToQueue(&record
);
132 void TrafficRecorder::RecordClientToServerMessage(
133 const sync_pb::ClientToServerMessage
& msg
) {
134 StoreProtoInQueue(msg
, CLIENT_TO_SERVER_MESSAGE
);
137 void TrafficRecorder::RecordClientToServerResponse(
138 const sync_pb::ClientToServerResponse
& response
) {
139 StoreProtoInQueue(response
, CLIENT_TO_SERVER_RESPONSE
);
142 } // namespace syncer