diff --git a/include/Sentry.h b/include/Sentry.h index 3080430..8495eb0 100644 --- a/include/Sentry.h +++ b/include/Sentry.h @@ -18,6 +18,8 @@ public: void AddExtra(const std::string& key, const std::string& value); void LogException(const std::exception& e, const std::string& file, const std::string& line); void AddErrorBreadcrumb(const std::string& msg, const std::string& file, const std::string& line); + // cleared when Logged + void SetTransaction(const std::string& id); private: bool mValid { true }; diff --git a/src/Http.cpp b/src/Http.cpp index b6945ff..af88442 100644 --- a/src/Http.cpp +++ b/src/Http.cpp @@ -87,7 +87,7 @@ std::string Http::POST(const std::string& host, const std::string& target, const //debug("IPv6 connect failed, trying IPv4"); bool ok = try_connect_with_protocol(tcp::v4()); if (!ok) { - //error("failed to resolve or connect in POST " + host + target); + Application::Console().Write("[ERROR] failed to resolve or connect in POST " + host + target); return "-1"; } //} @@ -97,7 +97,6 @@ std::string Http::POST(const std::string& host, const std::string& target, const req.set(http::field::host, host); if (!body.empty()) { if (json) { - // FIXME: json is untested. req.set(http::field::content_type, "application/json"); } else { req.set(http::field::content_type, "application/x-www-form-urlencoded"); @@ -125,9 +124,14 @@ std::string Http::POST(const std::string& host, const std::string& target, const http::read(stream, buffer, response); - auto BackendName = response.base().find("x-upstream"); - if (BackendName != response.base().end()) { - Sentry.AddExtra("x-upstream", BackendName->value().data()); + Sentry.AddExtra("reponse-code", std::to_string(response.result_int())); + + for (const auto& header : response.base()) { + // need to do explicit casts to convert string_view to string + // since string_view may not be null-terminated (and in fact isn't, here) + std::string KeyString(header.name_string()); + std::string ValueString(header.value()); + Sentry.AddExtra(KeyString, ValueString); } std::stringstream result; diff --git a/src/Sentry.cpp b/src/Sentry.cpp index 413ff03..d6029f6 100644 --- a/src/Sentry.cpp +++ b/src/Sentry.cpp @@ -11,6 +11,10 @@ TSentry::TSentry(const std::string& SentryUrl) { auto ReleaseString = "BeamMP-Server@" + Application::ServerVersion(); sentry_options_set_release(options, ReleaseString.c_str()); sentry_options_set_max_breadcrumbs(options, 10); + sentry_value_t user = sentry_value_new_object(); + sentry_value_set_by_key(user, "id", sentry_value_new_string(Application::Settings.Key.c_str())); + sentry_value_set_by_key(user, "ip_address", sentry_value_new_string("{{auto}}")); + sentry_set_user(user); sentry_init(options); } } @@ -35,6 +39,7 @@ void TSentry::Log(sentry_level_t level, const std::string& logger, const std::st } auto Msg = sentry_value_new_message_event(level, logger.c_str(), text.c_str()); sentry_capture_event(Msg); + sentry_remove_transaction(); } void TSentry::AddExtra(const std::string& key, const sentry_value_t& value) { @@ -66,3 +71,10 @@ void TSentry::AddErrorBreadcrumb(const std::string& msg, const std::string& file sentry_value_set_by_key(crumb, "level", sentry_value_new_string("error")); sentry_add_breadcrumb(crumb); } + +void TSentry::SetTransaction(const std::string& id) { + if (!mValid) { + return; + } + sentry_set_transaction(id.c_str()); +} diff --git a/src/THeartbeatThread.cpp b/src/THeartbeatThread.cpp index dc3d75a..cf83800 100644 --- a/src/THeartbeatThread.cpp +++ b/src/THeartbeatThread.cpp @@ -40,15 +40,17 @@ void THeartbeatThread::operator()() { if (T.substr(0, 2) != "20") { //Backend system refused server startup! std::this_thread::sleep_for(std::chrono::milliseconds(500)); - T = Http::POST(Application::GetBackendHostname(), "/heartbeat", {}, Body, false); + auto Target = "/heartbeat"; + T = Http::POST(Application::GetBackendHostname(), Target, {}, Body, false); // TODO backup2 + HTTP flag (no TSL) if (T.substr(0, 2) != "20") { warn("Backend system refused server! Server might not show in the public list"); debug("server returned \"" + T + "\""); if (T.size() > std::string("YOU_SHALL_NOT_PASS").size() && Application::Settings.Key.size() == 36) { - Sentry.AddExtra("response", T); - Sentry.AddExtra("body", Body); + Sentry.AddExtra("response-body", T); + Sentry.AddExtra("request-body", Body); + Sentry.SetTransaction(Application::GetBackendHostname() + Target); Sentry.Log(SENTRY_LEVEL_ERROR, "default", "wrong backend response format"); } isAuth = false; diff --git a/src/TNetwork.cpp b/src/TNetwork.cpp index 1ff7525..d452a1c 100644 --- a/src/TNetwork.cpp +++ b/src/TNetwork.cpp @@ -282,8 +282,9 @@ void TNetwork::Authentication(SOCKET TCPSock) { auto RequestString = R"({"key":")" + Rc + "\"}"; + auto Target = "/pkToUser"; if (!Rc.empty()) { - Rc = Http::POST(Application::GetBackendUrlForAuth(), "/pkToUser", {}, RequestString, true); + Rc = Http::POST(Application::GetBackendUrlForAuth(), Target, {}, RequestString, true); } json::Document AuthResponse; @@ -296,8 +297,9 @@ void TNetwork::Authentication(SOCKET TCPSock) { if (!AuthResponse.IsObject() && Rc != "0") { ClientKick(*Client, "Backend returned invalid auth response format."); error("Backend returned invalid auth response format. This should never happen."); - Sentry.AddExtra("response", Rc); + Sentry.AddExtra("response-body", Rc); Sentry.AddExtra("key", RequestString); + Sentry.SetTransaction(Application::GetBackendUrlForAuth() + Target); Sentry.Log(SENTRY_LEVEL_ERROR, "default", "auth: wrong backend response format"); return; }