mirror of
https://github.com/Dingo-Shenanigans/ReSkate.git
synced 2026-10-18 02:47:01 +02:00
Crash dumps now go to the project's own Sentry server. The launcher's out-of-process helper is unchanged; only where it posts and what it expects back are: - The default endpoint is the Sentry project's minidump URL. Report attributes travel as Sentry tags, with the release as reskate@<version>. - An upload counts as accepted when the server answers with an event ID. - "backtrace" is "crash_report" throughout: the namespace, files, CMake targets, DINGOSDK_CRASH_REPORT_URL, DINGOSDK_BUILD_CRASH_REPORT_TESTS and the RESKATE_CRASH_REPORT_URL override. Performance timings are new, and off unless "Send performance timings" is ticked in the launcher's settings (RESKATE_TRACING=1). A small tracer (Engine/Core/Debug/trace.h) posts each finished step to Sentry as a transaction from a background thread; the launcher and the game it starts share one trace. Timed: the update check, the Steam download, Thunderstore installs, the mod merge, starting the game, the launch up to the first playable level, each level load, joining a session, fetching the identity lists, and the time spent in each level with its average frame rate and long frames. Turning crash reports off turns timings off too.
66 lines
2.9 KiB
C++
66 lines
2.9 KiB
C++
#pragma once
|
|
#include <chrono>
|
|
#include <cstdint>
|
|
#include <exception>
|
|
#include <string>
|
|
#include <string_view>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
namespace dingosdk::trace {
|
|
using Tags = std::vector<std::pair<std::string, std::string>>;
|
|
using Clock = std::chrono::system_clock;
|
|
// A number carried by a transaction, such as an average frame rate.
|
|
struct Measurement { std::string name; double value{}; std::string unit{"none"}; };
|
|
using Measurements = std::vector<Measurement>;
|
|
// Called once logging is up: true when this launch sends timings. Until then,
|
|
// and in programs that never call it, record() does nothing. Timings are off
|
|
// unless RESKATE_TRACING=1 (the launcher's "Send performance timings" setting),
|
|
// and off whenever crash reporting is (RESKATE_CRASH_REPORTING=0).
|
|
bool start() noexcept;
|
|
// Queues one finished operation as a Sentry transaction. Never waits on the
|
|
// network and never throws. A launch's launcher and game share one trace.
|
|
void record(std::string_view name, std::string_view operation, std::chrono::milliseconds duration,
|
|
bool ok = true, Tags tags = {}, Measurements measurements = {}) noexcept;
|
|
// Frame pacing between two takes: the game's frame hook feeds it, and the end
|
|
// of a level session takes it. A hitch is a frame of 50 ms or longer.
|
|
struct FramePacing { std::uint64_t frames{}, total_ns{}, hitches{}, worst_ns{}; };
|
|
void frame(std::uint64_t now_ns) noexcept;
|
|
FramePacing take_frame_pacing() noexcept;
|
|
// Gives queued operations a moment to reach the server before the process exits.
|
|
void flush(std::chrono::milliseconds timeout) noexcept;
|
|
|
|
// Times its own lifetime. An exception passing through marks the operation failed.
|
|
class Scope {
|
|
public:
|
|
Scope(std::string name, std::string operation)
|
|
: name_(std::move(name)), operation_(std::move(operation)) {}
|
|
~Scope() {
|
|
record(name_, operation_, std::chrono::duration_cast<std::chrono::milliseconds>(
|
|
std::chrono::steady_clock::now() - started_), ok_ && std::uncaught_exceptions() == exceptions_, std::move(tags_));
|
|
}
|
|
Scope(const Scope&) = delete;
|
|
Scope& operator=(const Scope&) = delete;
|
|
void tag(std::string key, std::string value) { tags_.emplace_back(std::move(key), std::move(value)); }
|
|
void fail() noexcept { ok_ = false; }
|
|
private:
|
|
std::string name_, operation_;
|
|
Tags tags_;
|
|
std::chrono::steady_clock::time_point started_{std::chrono::steady_clock::now()};
|
|
int exceptions_{std::uncaught_exceptions()};
|
|
bool ok_{true};
|
|
};
|
|
|
|
struct Transaction {
|
|
std::string name, operation, trace_id, release, process;
|
|
Clock::time_point started, finished;
|
|
bool ok{true};
|
|
Tags tags;
|
|
Measurements measurements;
|
|
};
|
|
// The Sentry envelope for one transaction: envelope header, item header, payload.
|
|
std::string envelope(const Transaction& transaction);
|
|
// The envelope endpoint beside a minidump endpoint, or empty when the URL is not one.
|
|
std::wstring envelope_url(std::wstring_view minidump_url);
|
|
}
|