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 "remoting/client/server_log_entry_client.h" 6 7 #include "base/strings/string_number_conversions.h" 8 #include "base/strings/stringize_macros.h" 9 #include "base/strings/stringprintf.h" 10 #include "base/sys_info.h" 11 #include "remoting/client/chromoting_stats.h" 12 #include "remoting/jingle_glue/server_log_entry.h" 13 14 using base::StringPrintf; 15 using base::SysInfo; 16 using remoting::protocol::ConnectionToHost; 17 using remoting::protocol::ErrorCode; 18 19 namespace remoting { 20 21 namespace { 22 const char kValueRoleClient[] = "client"; 23 24 const char kValueEventNameSessionState[] = "session-state"; 25 const char kValueEventNameStatistics[] = "connection-statistics"; 26 const char kValueEventNameSessionIdOld[] = "session-id-old"; 27 const char kValueEventNameSessionIdNew[] = "session-id-new"; 28 29 const char kKeySessionId[] = "session-id"; 30 const char kKeySessionDuration[] = "session-duration"; 31 32 const char kKeySessionState[] = "session-state"; 33 const char kKeyConnectionError[] = "connection-error"; 34 const char kValueSessionStateConnected[] = "connected"; 35 const char kValueSessionStateClosed[] = "closed"; 36 37 const char kKeyOsName[] = "os-name"; 38 const char kKeyOsVersion[] = "os-version"; 39 const char kKeyAppVersion[] = "app-version"; 40 41 const char* GetValueSessionState(ConnectionToHost::State state) { 42 switch (state) { 43 // Where possible, these are the same strings that the webapp sends for the 44 // corresponding state - see remoting/webapp/server_log_entry.js. 45 case ConnectionToHost::INITIALIZING: 46 return "initializing"; 47 case ConnectionToHost::CONNECTING: 48 return "connecting"; 49 case ConnectionToHost::AUTHENTICATED: 50 return "authenticated"; 51 case ConnectionToHost::CONNECTED: 52 return kValueSessionStateConnected; 53 case ConnectionToHost::FAILED: 54 return "connection-failed"; 55 case ConnectionToHost::CLOSED: 56 return kValueSessionStateClosed; 57 default: 58 NOTREACHED(); 59 return NULL; 60 } 61 } 62 63 const char* GetValueError(ErrorCode error) { 64 switch (error) { 65 // Where possible, these are the same strings that the webapp sends for the 66 // corresponding error - see remoting/webapp/server_log_entry.js. 67 case protocol::OK: 68 return "none"; 69 case protocol::PEER_IS_OFFLINE: 70 return "host-is-offline"; 71 case protocol::SESSION_REJECTED: 72 return "session-rejected"; 73 case protocol::INCOMPATIBLE_PROTOCOL: 74 return "incompatible-protocol"; 75 case protocol::AUTHENTICATION_FAILED: 76 return "authentication-failed"; 77 case protocol::CHANNEL_CONNECTION_ERROR: 78 return "channel-connection-error"; 79 case protocol::SIGNALING_ERROR: 80 return "signaling-error"; 81 case protocol::SIGNALING_TIMEOUT: 82 return "signaling-timeout"; 83 case protocol::HOST_OVERLOAD: 84 return "host-overload"; 85 case protocol::UNKNOWN_ERROR: 86 return "unknown-error"; 87 default: 88 NOTREACHED(); 89 return NULL; 90 } 91 } 92 93 } // namespace 94 95 scoped_ptr<ServerLogEntry> MakeLogEntryForSessionStateChange( 96 ConnectionToHost::State state, 97 ErrorCode error) { 98 scoped_ptr<ServerLogEntry> entry(new ServerLogEntry()); 99 entry->AddRoleField(kValueRoleClient); 100 entry->AddEventNameField(kValueEventNameSessionState); 101 102 entry->Set(kKeySessionState, GetValueSessionState(state)); 103 if (error != protocol::OK) { 104 entry->Set(kKeyConnectionError, GetValueError(error)); 105 } 106 107 return entry.Pass(); 108 } 109 110 scoped_ptr<ServerLogEntry> MakeLogEntryForStatistics( 111 ChromotingStats* statistics) { 112 scoped_ptr<ServerLogEntry> entry(new ServerLogEntry()); 113 entry->AddRoleField(kValueRoleClient); 114 entry->AddEventNameField(kValueEventNameStatistics); 115 116 entry->Set("video-bandwidth", 117 StringPrintf("%.2f", statistics->video_bandwidth()->Rate())); 118 entry->Set("capture-latency", 119 StringPrintf("%.2f", statistics->video_capture_ms()->Average())); 120 entry->Set("encode-latency", 121 StringPrintf("%.2f", statistics->video_encode_ms()->Average())); 122 entry->Set("decode-latency", 123 StringPrintf("%.2f", statistics->video_decode_ms()->Average())); 124 entry->Set("render-latency", 125 StringPrintf("%.2f", statistics->video_frame_rate()->Rate())); 126 entry->Set("roundtrip-latency", 127 StringPrintf("%.2f", statistics->round_trip_ms()->Average())); 128 129 return entry.Pass(); 130 } 131 132 scoped_ptr<ServerLogEntry> MakeLogEntryForSessionIdOld( 133 const std::string& session_id) { 134 scoped_ptr<ServerLogEntry> entry(new ServerLogEntry()); 135 entry->AddRoleField(kValueRoleClient); 136 entry->AddEventNameField(kValueEventNameSessionIdOld); 137 AddSessionIdToLogEntry(entry.get(), session_id); 138 return entry.Pass(); 139 } 140 141 scoped_ptr<ServerLogEntry> MakeLogEntryForSessionIdNew( 142 const std::string& session_id) { 143 scoped_ptr<ServerLogEntry> entry(new ServerLogEntry()); 144 entry->AddRoleField(kValueRoleClient); 145 entry->AddEventNameField(kValueEventNameSessionIdNew); 146 AddSessionIdToLogEntry(entry.get(), session_id); 147 return entry.Pass(); 148 } 149 150 void AddClientFieldsToLogEntry(ServerLogEntry* entry) { 151 entry->Set(kKeyOsName, SysInfo::OperatingSystemName()); 152 entry->Set(kKeyOsVersion, SysInfo::OperatingSystemVersion()); 153 entry->Set(kKeyAppVersion, STRINGIZE(VERSION)); 154 entry->AddCpuField(); 155 } 156 157 void AddSessionIdToLogEntry(ServerLogEntry* entry, const std::string& id) { 158 entry->Set(kKeySessionId, id); 159 } 160 161 void AddSessionDurationToLogEntry(ServerLogEntry* entry, 162 base::TimeDelta duration) { 163 entry->Set(kKeySessionDuration, base::Int64ToString(duration.InSeconds())); 164 } 165 166 } // namespace remoting 167