-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SSmetrics - Elasticsearch powered metrics viewing #16549
Changes from 9 commits
2ece320
dcad174
ac9ff53
51e22b4
09e8649
9e69cce
94315d4
b9b022d
4590736
eb03d05
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
/// Config holder for stuff relating to metrics management | ||
/datum/configuration_section/metrics_configuration | ||
// NO EDITS OR READS TO THIS EVER | ||
protection_state = PROTECTION_PRIVATE | ||
/// Are metrics enabled or disabled | ||
var/enable_metrics = FALSE | ||
/// Endpoint to send metrics to, including protocol | ||
var/metrics_endpoint = null | ||
/// Endpoint authorisation API key | ||
var/metrics_api_token = null | ||
|
||
/datum/configuration_section/metrics_configuration/load_data(list/data) | ||
// Use the load wrappers here. That way the default isnt made 'null' if you comment out the config line | ||
CONFIG_LOAD_BOOL(enable_metrics, data["enable_metrics"]) | ||
|
||
CONFIG_LOAD_STR(metrics_endpoint, data["metrics_endpoint"]) | ||
CONFIG_LOAD_STR(metrics_api_token, data["metrics_api_token"]) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,8 @@ | |
/datum/controller/subsystem | ||
// Metadata; you should define these. | ||
name = "fire codertrain" //name of the subsystem | ||
/// Subsystem ID. Used for when we need a technical name for the SS | ||
var/ss_id = "fire_codertrain_again" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👌 |
||
var/init_order = INIT_ORDER_DEFAULT //order of initialization. Higher numbers are initialized first, lower numbers later. Use defines in __DEFINES/subsystems.dm for easy understanding of order. | ||
var/wait = 20 //time to wait (in deciseconds) between each call to fire(). Must be a positive integer. | ||
var/priority = FIRE_PRIORITY_DEFAULT //When mutiple subsystems need to run in the same tick, higher priority subsystems will run first and be given a higher share of the tick before MC_TICK_CHECK triggers a sleep | ||
|
@@ -227,3 +229,17 @@ | |
if("queued_priority") //editing this breaks things. | ||
return 0 | ||
. = ..() | ||
|
||
/** | ||
* Returns the metrics for the subsystem. | ||
* | ||
* This can be overriden on subtypes for variables that could affect tick usage | ||
* Example: ATs on SSair | ||
*/ | ||
/datum/controller/subsystem/proc/get_metrics() | ||
SHOULD_CALL_PARENT(TRUE) | ||
var/list/out = list() | ||
out["cost"] = cost | ||
out["tick_usage"] = tick_usage | ||
out["custom"] = list() // Override as needed on child | ||
return out |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,6 +11,11 @@ SUBSYSTEM_DEF(acid) | |
/datum/controller/subsystem/acid/stat_entry() | ||
..("P:[processing.len]") | ||
|
||
/datum/controller/subsystem/acid/get_metrics() | ||
. = ..() | ||
var/list/cust = list() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These being There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's for easier differentiation between the list index and the entry itself. I also recall something having a custom var and I didn't want these to interfere. |
||
cust["processing"] = length(processing) | ||
.["custom"] = cust | ||
|
||
/datum/controller/subsystem/acid/fire(resumed = 0) | ||
if(!resumed) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
SUBSYSTEM_DEF(metrics) | ||
name = "Metrics" | ||
wait = 30 SECONDS | ||
offline_implications = "Server metrics will no longer be ingested into monitoring systems. No immediate action is needed." | ||
runlevels = RUNLEVEL_LOBBY | RUNLEVEL_SETUP | RUNLEVEL_GAME | RUNLEVEL_POSTGAME // ALL THE LEVELS | ||
flags = SS_KEEP_TIMING // This needs to ingest every IRL minute | ||
AffectedArc07 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
/// The real time of day the server started. Used to calculate time drift | ||
var/world_init_time = 0 // Not set in here. Set in world/New() | ||
|
||
/datum/controller/subsystem/metrics/Initialize(start_timeofday) | ||
if(!GLOB.configuration.metrics.enable_metrics) | ||
flags |= SS_NO_FIRE // Disable firing to save CPU | ||
return ..() | ||
|
||
|
||
/datum/controller/subsystem/metrics/fire(resumed) | ||
SShttp.create_async_request(RUSTG_HTTP_METHOD_POST, GLOB.configuration.metrics.metrics_endpoint, get_metrics_json(), list( | ||
"Authorization" = "ApiKey [GLOB.configuration.metrics.metrics_api_token]", | ||
"Content-Type" = "application/json" | ||
)) | ||
|
||
/datum/controller/subsystem/metrics/proc/get_metrics_json() | ||
var/list/out = list() | ||
out["@timestamp"] = time_stamp() // This is required by ElasticSearch, complete with this name. DO NOT REMOVE THIS. | ||
out["cpu"] = world.cpu | ||
// out["maptick"] = world.map_cpu // TODO: 514 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
out["elapsed_processed"] = world.time | ||
out["elapsed_real"] = (REALTIMEOFDAY - world_init_time) | ||
out["client_count"] = length(GLOB.clients) | ||
out["round_id"] = text2num(GLOB.round_id) // This is so we can filter the metrics by a single round ID | ||
|
||
// Funnel in all SS metrics | ||
var/list/ss_data = list() | ||
for(var/datum/controller/subsystem/SS in Master.subsystems) | ||
ss_data[SS.ss_id] = SS.get_metrics() | ||
AffectedArc07 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
out["subsystems"] = ss_data | ||
// And send it all | ||
return json_encode(out) | ||
|
||
/* | ||
|
||
// Uncomment this if you add new metrics to verify how the JSON formats | ||
|
||
/client/verb/debugmetricts() | ||
usr << browse(SSmetrics.get_metrics_json(), "window=aadebug") | ||
*/ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
// Unit test to ensure SS metrics are valid | ||
/datum/unit_test/subsystem_metric_sanity/Run() | ||
for(var/datum/controller/subsystem/SS in Master.subsystems) | ||
var/list/data = SS.get_metrics() | ||
if(length(data) != 3) | ||
Fail("SS[SS.ss_id] has invalid metrics data!") | ||
continue | ||
if(isnull(data["cost"])) | ||
Fail("SS[SS.ss_id] has invalid metrics data! No 'cost' found in [json_encode(data)]") | ||
continue | ||
if(isnull(data["tick_usage"])) | ||
Fail("SS[SS.ss_id] has invalid metrics data! No 'tick_usage' found in [json_encode(data)]") | ||
continue | ||
if(isnull(data["custom"])) | ||
Fail("SS[SS.ss_id] has invalid metrics data! No 'custom' found in [json_encode(data)]") | ||
continue | ||
if(!islist(data["custom"])) | ||
Fail("SS[SS.ss_id] has invalid metrics data! 'custom' is not a list in [json_encode(data)]") | ||
continue |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a typo fix