...

Package metrics

import "github.com/Diarkis/diarkis/metrics"
Overview
Index

Overview ▾

Package metrics ▷

Metrics

Allows you to extend built-in metrics data with your own custom metrics names and values.

Configurations

Metrics package has optional configurations for adding customized metrics from your application.

{
  "names": [ $(name) ... ],
  "namesWithLabels": [ $(name) ... ]
}

Configuration properties

name           - A list of custom metrics names to be used.
                 Each name must have value update function assigned.
nameWithLabels - A list of custom metrics names with custom labels.
                 Each name must have value update function assigned.

Custom Metrics Example

In order to add your own custom metrics, you must have a configuration JSON file and have HTTP and your other server (TCP/UDP) read it.

The example shown below will explain how it is done:

HTTP servers must load the configuration file containing the names of custom metrics.

// You must call metrics.Setup() before calling diarkis.Start()
metrics.Setup("/absolute/path/to/my/config/JSON/file")

The custom metrics names must match the parameters given to metrics.DefineMetricsValue in the network servers (UDP and/or TCP and/or custom type servers).

Network Server (UDP and/or TCP and/or custom type servers) Example

UDP and/or TCP and/or custom type server must also load the configuration file containing the names of custom metrics. Additionally, the server must also need to define how the values of custom metrics should be counted as shown as an example below:

// You must call metrics.Setup() before calling diarkis.Start()
// You also must call metrics.Setup after calling mesh.Setup(...)
metrics.Setup("/absolute/path/to/my/config/JSON/file")

// Make sure the name used here is configured in the config JSON file: "names": [ "MyCustomMetrics" ]
customMetricsName := "MyCustomMetrics"

// You must call metrics.Setup() before calling diarkis.Start()
// You also must call metrics.Setup after calling mesh.Setup(...)
// The callback function assigned here will be invoked at every mesh package update
metrics.DefineMetricsValue(customMetricsName, func() int {

  // returned value will be your custom metrics value
  return customMetricsValue

})

# Custom Metrics with Label Example When you need custom metrics with custom or dynamic labels, you can use DefineMetricsValueWithLabel.

The example shown below will explain how it is done:

Let's say you want the output below for Prometheus metrics:

AVG_RETRY_UDP_node{type="TRN",id="TRN:127.0.0.1:8101",endpoint="127.0.0.1:7200",status="online",mode="pve",tag="ranked"} 89
AVG_RETRY_UDP_node{type="TRN",id="TRN:127.0.0.1:8101",endpoint="127.0.0.1:7200",status="online",mode="pvp",tag="ranked"} 27
AVG_RETRY_UDP_node{type="TRN",id="TRN:127.0.0.1:8101",endpoint="127.0.0.1:7200",status="online",mode="pve",tag="quick"} 25
AVG_RETRY_UDP_node{type="TRN",id="TRN:127.0.0.1:8101",endpoint="127.0.0.1:7200",status="online",mode="pvp",tag="quick"} 95

You firstly need to define the metrics name in the configuration file:

 {
	  "namesWithLabels": ["ISSUED_TICKET"]
 }

Then you need to pass a callback function that returns a slice of LabelValue struct to DefineMetricsValueWithLabel:

  type Key struct {
  	mode string
  	tag  string
  }

  var ticketStat = map[Key]int{
  	Key{mode: "pve", tag: "ranked"}: 89,
  	Key{mode: "pvp", tag: "ranked"}: 27,
  	Key{mode: "pve", tag: "quick"}:  25,
  	Key{mode: "pvp", tag: "quick"}:  95,
  }

  func Setup(rootpath string) {
  	metrics.Setup((fmt.Sprintf("%s/configs/shared/metrics.json", rootpath)))
  	metrics.DefineMetricsValueWithLabel("ISSUED_TICKET", getTicketMetrics)
  	mesh.OnUpdate(updateTicketStat)
  }

  func getTicketMetrics() (values []*metrics.LabelValue) {
	for k, v := range ticketStat {
		lv := &metrics.LabelValue{
			Value:  v,
			Labels: map[string]string{"mode": k.mode, "tag": k.tag},
		}
		values = append(values, lv)
	}
	return values
  }

Now every time you call /metrics/prometheus/v/3, you will get the custom metrics with labels.

Built-in Metrics

Diarkis has built-in metrics that you may use out-of-the-box. This section will explain each built-in metrics.

$(server_type) is a variable that depends on what server types you have in your Diarkis server cluster.

▶︎ CCU Count

Users_$(server_type)_node

CCU (Concurrent Users) per server (node). This number represents the currently connected and active client devices per server.

▶︎ Room Count

Rooms_$(server_type)_node

Represents how many rooms exists on a server (node).

▶︎ Group Count

Groups_$(server_type)_node

Represents how many groups exists on a server (node). Since Diarkis Group is distributed through out the entire Diarkis server cluster, the number of groups may be redundant across multiple servers. It means that multiple count of groups on multiple servers may represents a single group.

▶︎ Inbound Packet Count

UDP_Packets_In_$(server_type)_node

Represents the number of received inbound UDP packets on a server (node).

▶︎ Outbound Packet Count

UDP_Packets_Out_$(server_type)_node

Represents the number of outbound UDP packets sent from a server (node).

▶︎ Inbound Command Count

Commands_In_$(server_type)_node

Represents the number of received inbound commands on a server (node). A single packet may contain multiple commands.

▶︎ Outbound Command Count

Commands_Out_$(server_type)_node

Represents the number of outbound commands sent from a server (node). A single packet may contain multiple commands.

▶︎ Outbound RUDP Retry Packet Count

RUDP_Retries_$(server_type)_node

Represents the number of outbound RUDP retry packets sent from a server (node).

▶︎ Inbound RUDP Split Packet Count

RUDP_Split_In_$(server_type)_node

Represents the number of received inbound RUDP split packets on a server (node). When the client sent a RUDP packet that exceeds MTU, Diarkis automatically split the packet into smaller packets and send them separately.

▶︎ Outbound RUDP Split Packet Count

RUDP_Split_Out_$(server_type)_node

Represents the number of outbound RUDP split packets sent from a server (node). When the client sent a RUDP packet that exceeds MTU, Diarkis automatically split the packet into smaller packets and send them separately.

▶︎ Inbound Internal Packet Count

Mesh_Packets_In_($server_type)_node

Represents the number of received inbound internal packets on a server (node). Every Diarkis server is able to send and receive packets internally.

▶︎ Outbound Internal Packet Count

Mesh_Packets_Out_$(server_type)_node

Represents the number of outbound packets sent from a server (node). Every Diarkis server is able to send and receive packets internally.

▶︎ Outbound Internal Retry Packet Count

Mesh_Retry_$(server_type)_node

Represents the number of outbound retried internal packets sent from a server (node). Every Diarkis server is able to send and receive packets internally. Increase of this number usually indicates the increase of server workload.

▶︎ MatchMaker Internal Search Count

MatchMaker_Search_$(server_type)_node

Represents the number of executed matchmaking internal searches. A single MatchMaker search may execute multiple internal searches.

▶︎ MatchMaker Internal Empty Search Result Count

MatchMaker_Empty_$(server_type)_node

Represents the number of empty internal search results. A single MatchMaker search may execute multiple internal searches.

▶︎ MatchMaker Issued Ticket Count

MatchMaker_Ticket_$(server_type)_node

Represents the number of issued MatchMaker Tickets.

▶︎ MatchMaker Ticket Search Count

MatchMaker_Ticket_Search_$(server_type)_node

Represents the number of ticket searches executed. Ticket searches target waiting tickets.

▶︎ MatchMaker Ticket Add (Wait) Count

MatchMaker_Ticket_Add_$(server_type)_node

Represents the number of waiting tickets. Waiting tickets are to be searched and found by ticket searches.

▶︎ MatchMaker Ticket Successful Completion Count

MatchMaker_Complete_UDP_node

Represents the number of successfully completed tickets.

▶︎ MatchMaker Ticket Completion Average Time

MatchMaker_Ticket_Complete_Time_Avg_$(server_type)_node

Represents the average time a ticket takes to successfully complete in seconds.

▶︎ MatchMaker Ticket Completion Minimum Time

MatchMaker_Ticket_Complete_Time_Min_$(server_type)_node

Represents the minimum time a ticket takes to successfully complete in seconds.

▶︎ MatchMaker Ticket Completion Maximum Time

MatchMaker_Ticket_Complete_Time_Max_$(server_type)_node

Represents the maximum time a ticket takes to successfully complete in seconds.

▶︎ P2P Success Count

P2P_Success_$(server_type)_node

Represents the number of successful peer-to-peer hole punchings.

▶︎ P2P Attempt Count

P2P_Attempt_$(server_type)_node

Represents the number of peer-to-peer attempts by the client.

Constants

FieldGridName used in field

const FieldGridName = "Field_Grids"

FieldMeshGridCntName used in field

const FieldMeshGridCntName = "fg"

GroupMeshVaultName used in group

const GroupMeshVaultName = "g"

GroupVaultName used in group

const GroupVaultName = "Groups"

MatchMakerCompleteCnt used in matching

const MatchMakerCompleteCnt = "mc"

MatchMakerCompleteName used in matching

const MatchMakerCompleteName = "MatchMaker_Complete"

MatchMakerEmptySearchCnt used in matching

const MatchMakerEmptySearchCnt = "me"

MatchMakerEmptySearchName used in matching

const MatchMakerEmptySearchName = "MatchMaker_Empty"

MatchMakerSearchCnt used in matching

const MatchMakerSearchCnt = "ms"

MatchMakerSearchName used in matching

const MatchMakerSearchName = "MatchMaker_Search"

MatchMakerTicketAddCnt used in matching

const MatchMakerTicketAddCnt = "mta"

MatchMakerTicketAddName used in matching

const MatchMakerTicketAddName = "MatchMaker_Ticket_Add"

MatchMakerTicketCnt used in matching

const MatchMakerTicketCnt = "mt"

MatchMakerTicketCompleteTimeAvg used in matching

const MatchMakerTicketCompleteTimeAvg = "mtt"

MatchMakerTicketCompleteTimeAvgName used in matching

const MatchMakerTicketCompleteTimeAvgName = "MatchMaker_Ticket_Complete_Time_Avg"

MatchMakerTicketCompleteTimeMax used in matching

const MatchMakerTicketCompleteTimeMax = "mtx"

MatchMakerTicketCompleteTimeMaxName used in matching

const MatchMakerTicketCompleteTimeMaxName = "MatchMaker_Ticket_Complete_Time_Max"

MatchMakerTicketCompleteTimeMin used in matching

const MatchMakerTicketCompleteTimeMin = "mtn"

MatchMakerTicketCompleteTimeMinName used in matching

const MatchMakerTicketCompleteTimeMinName = "MatchMaker_Ticket_Complete_Time_Min"

MatchMakerTicketName used in matching

const MatchMakerTicketName = "MatchMaker_Ticket"

MatchMakerTicketSearchCnt used in matching

const MatchMakerTicketSearchCnt = "mts"

MatchMakerTicketSearchName used in matching

const MatchMakerTicketSearchName = "MatchMaker_Ticket_Search"

MeshPktSampleIn used in mesh

const MeshPktSampleIn = "mi"

MeshPktSampleInName used in mesh

const MeshPktSampleInName = "Mesh_Packets_In"

MeshPktSampleOut used in mesh

const MeshPktSampleOut = "mo"

MeshPktSampleOutName used in mesh

const MeshPktSampleOutName = "Mesh_Packets_Out"

MeshPktSampleRetry used in mesh

const MeshPktSampleRetry = "mr"

MeshPktSampleRetryName used in mesh

const MeshPktSampleRetryName = "Mesh_Retry"

P2PAttemptCnt used in P2P

const P2PAttemptCnt = "pa"

P2PAttemptName used in P2P attempt count report

const P2PAttemptName = "P2P_Attempt"

P2PSuccessCnt used in P2P success count report

const P2PSuccessCnt = "ps"

P2PSuccessName used in P2P success count report

const P2PSuccessName = "P2P_Success"

RoomMeshVaultName used in room

const RoomMeshVaultName = "r"

RoomVaultName used in room

const RoomVaultName = "Rooms"

TCPPktSampleIn used in tcp

const TCPPktSampleIn = "ti"

TCPPktSampleInName used in tcp

const TCPPktSampleInName = "TCP_Packets_In"

TCPPktSampleOut used in tcp

const TCPPktSampleOut = "to"

TCPPktSampleOutName used in tcp

const TCPPktSampleOutName = "TCP_Packets_Out"

TCPPktSampleSizeIn used in tcp

const TCPPktSampleSizeIn = "tsi"

TCPPktSampleSizeInName used in tcp

const TCPPktSampleSizeInName = "TCP_Packet_Size_In"

TCPPktSampleSizeOut used in tcp

const TCPPktSampleSizeOut = "tso"

TCPPktSampleSizeOutName used in tcp

const TCPPktSampleSizeOutName = "TCP_Packet_Size_Out"

UDPCmdSample used in udp

const UDPCmdSample = "um"

UDPCmdSampleName used in udp

const UDPCmdSampleName = "Commands_In"

UDPPktSampleIn used in udp

const UDPPktSampleIn = "ui"

UDPPktSampleInName used in udp

const UDPPktSampleInName = "UDP_Packets_In"

UDPPktSampleOut used in udp

const UDPPktSampleOut = "uo"

UDPPktSampleOutName used in udp

const UDPPktSampleOutName = "UDP_Packets_Out"

UDPPktSampleSizeIn used in udp

const UDPPktSampleSizeIn = "usi"

UDPPktSampleSizeInName used in udp

const UDPPktSampleSizeInName = "UDP_Packet_Size_In"

UDPPktSampleSizeOut used in udp

const UDPPktSampleSizeOut = "uso"

UDPPktSampleSizeOutName used in udp

const UDPPktSampleSizeOutName = "UDP_Packet_Size_Out"

UDPRetrySample used in udp

const UDPRetrySample = "ur"

UDPRetrySampleName used in udp

const UDPRetrySampleName = "RUDP_Retries"

UDPSendSample used in udp

const UDPSendSample = "us"

UDPSendSampleName used in udp

const UDPSendSampleName = "Commands_Out"

UDPSplitSampleIn used in udp

const UDPSplitSampleIn = "si"

UDPSplitSampleInName used in udp

const UDPSplitSampleInName = "RUDP_Split_In"

UDPSplitSampleOut used in udp

const UDPSplitSampleOut = "so"

UDPSplitSampleOutName used in udp

const UDPSplitSampleOutName = "RUDP_Split_Out"

UserMeshVaultName used in user

const UserMeshVaultName = "uc"

UserVaultName used in user

const UserVaultName = "Users"

func DefineMetricsValue

func DefineMetricsValue(name string, cb ValueUpdate) error

DefineMetricsValue defines the value update operation of the metrics name given.

[IMPORTANT] MUST invoke this function BEFORE calling diarkis.Start()
[IMPORTANT] MUST invoke this function AFTER calling mesh.Setup(...)

Error Cases

┌────────────────────────────────────────────────┬──────────────────────────────────────────────────────────────────────────────┐
│ Error                                          │ Reason                                                                       │
├────────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────────────┤
│ Setup must invoked at the start of the process │ Invoking this function without calling Setup() is not allowed.               │
│ Must be invoked BEFORE the start of Diarkis    │ Invoking this function after the start of Diarkis is not allowed.            │
│ Metrics name must be configured                │ All metrics names must be configured in the configuration file.              │
│ Metrics value update function already assigned │ Assigning multiple value update functions for a metrics name is not allowed. │
└────────────────────────────────────────────────┴──────────────────────────────────────────────────────────────────────────────┘

The name must be configured in a configuration file.

func DefineMetricsValueWithLabel

func DefineMetricsValueWithLabel(name string, cb ValueLabelUpdate) error

DefineMetricsValueWithLabel defines the value update operation of the metrics name and label given. Currently it only works for Prometheus metrics. See the documentation for DefineMetricsValue for more information

func GetMetricsValues

func GetMetricsValues(nodeType string) map[string][]*Item

GetMetricsValues [INTERNAL USE ONLY] returns all metrics values with the configured names and update functions

func PassMeshGetNodeAddressesByRole

func PassMeshGetNodeAddressesByRole(cb func(string) []string)

PassMeshGetNodeAddressesByRole [INTERNAL USE ONLY]

func PassMeshGetNodeTypeByAddress

func PassMeshGetNodeTypeByAddress(cb func(string) string)

PassMeshGetNodeTypeByAddress [INTERNAL USE ONLY]

func PassMeshGetNodeValue

func PassMeshGetNodeValue(cb func(string, string) interface{})

PassMeshGetNodeValue [INTERNAL USE ONLY]

func PassMeshOnUpdate

func PassMeshOnUpdate(cb func(func()))

PassMeshOnUpdate [INTERNAL USE ONLY]

func PassMeshSetNodeValue

func PassMeshSetNodeValue(cb func(string, interface{}))

PassMeshSetNodeValue [INTERNAL USE ONLY]

func Setup

func Setup(path string)

Setup must be invoked at the start of the process in order to use metrics.

[IMPORTANT] Must invoke this function BEFORE calling diarkis.Start()
[IMPORTANT] MUST invoke this function AFTER calling mesh.Setup(...)

type Item

Item [INTERNAL USE ONLY] represents a metrics value

type Item struct {
    Addr   string
    Value  interface{}
    Type   string
    Labels map[string]string
}

type LabelValue

LabelValue map[map[string]string]int

type LabelValue struct {
    Value  interface{}       `json:"v"`
    Labels map[string]string `json:"l"`
}

type ValueLabelUpdate

ValueLabelUpdate is a function that updates the associated metrics value by using the returned value as its associated metrics label and value.

type ValueLabelUpdate func() (value []*LabelValue)

type ValueUpdate

ValueUpdate is a function that updates the associated metrics value by using the returned value as its associated metrics value.

type ValueUpdate func() (value int)