mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-10-05 12:23:44 +00:00
feat: web dashboard and playground work
The NexusDashboard-parity dashboard (dDashboardServer) and everything built on it on the experimental branch: accounts, characters, properties and moderation tools, permissions shared with in-game slash commands, economy reports, World 3D and property 3D views with client scenery, scheduled events (features, vanity changes, live events, announcements, restarts), vanity files and events, the CDClient browser, the message inspector with saved captures, chat filter tools, community challenges, live ops, the AI moderator helper, and the server-side changes they need. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1215
docs/Dashboard.md
Normal file
1215
docs/Dashboard.md
Normal file
File diff suppressed because it is too large
Load Diff
585
docs/DasshboardWebAPI.yaml
Normal file
585
docs/DasshboardWebAPI.yaml
Normal file
@@ -0,0 +1,585 @@
|
||||
openapi: 3.0.0
|
||||
info:
|
||||
title: DarkflameServer Dashboard API
|
||||
description: |
|
||||
Game server management and monitoring API for DarkflameServer Dashboard.
|
||||
All protected endpoints require JWT authentication.
|
||||
version: 1.0.0
|
||||
contact:
|
||||
name: DarkflameServer Team
|
||||
url: https://github.com/DarkflameUniverse/DarkflameServer
|
||||
license:
|
||||
name: MIT
|
||||
|
||||
servers:
|
||||
- url: http://localhost:3000
|
||||
description: Local development server
|
||||
- url: https://api.example.com
|
||||
description: Production server
|
||||
|
||||
tags:
|
||||
- name: Authentication
|
||||
description: User login and token verification
|
||||
- name: Server
|
||||
description: Server status and information
|
||||
- name: Players
|
||||
description: Player and character management
|
||||
- name: Statistics
|
||||
description: Server statistics and counts
|
||||
|
||||
components:
|
||||
securitySchemes:
|
||||
bearerAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: JWT
|
||||
description: JWT token obtained from login endpoint
|
||||
queryToken:
|
||||
type: apiKey
|
||||
in: query
|
||||
name: token
|
||||
description: JWT token as query parameter
|
||||
cookieToken:
|
||||
type: apiKey
|
||||
in: cookie
|
||||
name: dashboardToken
|
||||
description: JWT token as HTTP-only cookie
|
||||
|
||||
schemas:
|
||||
LoginRequest:
|
||||
type: object
|
||||
required:
|
||||
- username
|
||||
- password
|
||||
properties:
|
||||
username:
|
||||
type: string
|
||||
minLength: 1
|
||||
example: admin
|
||||
password:
|
||||
type: string
|
||||
minLength: 1
|
||||
example: password123
|
||||
rememberMe:
|
||||
type: boolean
|
||||
default: false
|
||||
description: Extends token expiration to 30 days
|
||||
|
||||
LoginResponse:
|
||||
type: object
|
||||
required:
|
||||
- success
|
||||
- token
|
||||
- gmLevel
|
||||
- expiresIn
|
||||
properties:
|
||||
success:
|
||||
type: boolean
|
||||
example: true
|
||||
token:
|
||||
type: string
|
||||
description: JWT token for authenticated requests
|
||||
example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
||||
gmLevel:
|
||||
type: integer
|
||||
minimum: 0
|
||||
maximum: 9
|
||||
example: 9
|
||||
description: User's GM level (0-9)
|
||||
expiresIn:
|
||||
type: integer
|
||||
description: Token expiration time in seconds
|
||||
example: 86400
|
||||
|
||||
LoginError:
|
||||
type: object
|
||||
required:
|
||||
- success
|
||||
- error
|
||||
properties:
|
||||
success:
|
||||
type: boolean
|
||||
example: false
|
||||
error:
|
||||
type: string
|
||||
example: Invalid username or password
|
||||
|
||||
VerifyTokenRequest:
|
||||
type: object
|
||||
required:
|
||||
- token
|
||||
properties:
|
||||
token:
|
||||
type: string
|
||||
description: JWT token to verify
|
||||
example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
||||
|
||||
VerifyTokenResponse:
|
||||
type: object
|
||||
required:
|
||||
- valid
|
||||
- username
|
||||
- gmLevel
|
||||
- expiresAt
|
||||
properties:
|
||||
valid:
|
||||
type: boolean
|
||||
example: true
|
||||
username:
|
||||
type: string
|
||||
example: admin
|
||||
gmLevel:
|
||||
type: integer
|
||||
minimum: 0
|
||||
maximum: 9
|
||||
example: 9
|
||||
expiresAt:
|
||||
type: integer
|
||||
description: Unix timestamp when token expires
|
||||
example: 1705960800
|
||||
|
||||
VerifyTokenError:
|
||||
type: object
|
||||
required:
|
||||
- valid
|
||||
- error
|
||||
properties:
|
||||
valid:
|
||||
type: boolean
|
||||
example: false
|
||||
error:
|
||||
type: string
|
||||
example: Invalid or expired token
|
||||
|
||||
ServerStatus:
|
||||
type: object
|
||||
required:
|
||||
- status
|
||||
- version
|
||||
- uptime
|
||||
- timestamp
|
||||
properties:
|
||||
status:
|
||||
type: string
|
||||
enum:
|
||||
- running
|
||||
- stopping
|
||||
- restarting
|
||||
example: running
|
||||
version:
|
||||
type: string
|
||||
example: 1.0.0
|
||||
uptime:
|
||||
type: integer
|
||||
description: Server uptime in seconds
|
||||
example: 3600
|
||||
timestamp:
|
||||
type: integer
|
||||
description: Current Unix timestamp
|
||||
example: 1705960800
|
||||
|
||||
Player:
|
||||
type: object
|
||||
required:
|
||||
- id
|
||||
- name
|
||||
- level
|
||||
- character
|
||||
- zone
|
||||
- lastSeen
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
example: 1
|
||||
name:
|
||||
type: string
|
||||
example: PlayerOne
|
||||
level:
|
||||
type: integer
|
||||
minimum: 1
|
||||
maximum: 999
|
||||
example: 20
|
||||
character:
|
||||
type: string
|
||||
example: Knight
|
||||
zone:
|
||||
type: string
|
||||
example: Nimbus Station
|
||||
lastSeen:
|
||||
type: integer
|
||||
description: Unix timestamp of last activity
|
||||
example: 1705960750
|
||||
|
||||
PlayersResponse:
|
||||
type: object
|
||||
required:
|
||||
- players
|
||||
- total
|
||||
- limit
|
||||
- offset
|
||||
properties:
|
||||
players:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Player'
|
||||
total:
|
||||
type: integer
|
||||
description: Total number of players
|
||||
example: 42
|
||||
limit:
|
||||
type: integer
|
||||
description: Requested limit
|
||||
example: 50
|
||||
offset:
|
||||
type: integer
|
||||
description: Requested offset
|
||||
example: 0
|
||||
|
||||
AccountsCountRequest:
|
||||
type: object
|
||||
properties:
|
||||
includeInactive:
|
||||
type: boolean
|
||||
default: false
|
||||
description: Include inactive accounts in count
|
||||
|
||||
AccountsCountResponse:
|
||||
type: object
|
||||
required:
|
||||
- count
|
||||
- active
|
||||
- inactive
|
||||
- timestamp
|
||||
properties:
|
||||
count:
|
||||
type: integer
|
||||
description: Total account count
|
||||
example: 42
|
||||
active:
|
||||
type: integer
|
||||
description: Number of active accounts
|
||||
example: 35
|
||||
inactive:
|
||||
type: integer
|
||||
description: Number of inactive accounts
|
||||
example: 7
|
||||
timestamp:
|
||||
type: integer
|
||||
description: Unix timestamp when data was collected
|
||||
example: 1705960800
|
||||
|
||||
CharactersCountRequest:
|
||||
type: object
|
||||
properties:
|
||||
includeDeleted:
|
||||
type: boolean
|
||||
default: false
|
||||
description: Include deleted characters in count
|
||||
|
||||
CharactersCountResponse:
|
||||
type: object
|
||||
required:
|
||||
- count
|
||||
- active
|
||||
- deleted
|
||||
- timestamp
|
||||
properties:
|
||||
count:
|
||||
type: integer
|
||||
description: Total character count
|
||||
example: 128
|
||||
active:
|
||||
type: integer
|
||||
description: Number of active characters
|
||||
example: 125
|
||||
deleted:
|
||||
type: integer
|
||||
description: Number of deleted characters
|
||||
example: 3
|
||||
timestamp:
|
||||
type: integer
|
||||
description: Unix timestamp when data was collected
|
||||
example: 1705960800
|
||||
|
||||
Error:
|
||||
type: object
|
||||
required:
|
||||
- error
|
||||
- code
|
||||
- timestamp
|
||||
properties:
|
||||
error:
|
||||
type: string
|
||||
example: Authentication required
|
||||
code:
|
||||
type: integer
|
||||
enum:
|
||||
- 400
|
||||
- 401
|
||||
- 403
|
||||
- 404
|
||||
- 500
|
||||
example: 401
|
||||
timestamp:
|
||||
type: integer
|
||||
description: Unix timestamp
|
||||
example: 1705960800
|
||||
|
||||
responses:
|
||||
Unauthorized:
|
||||
description: Missing or invalid authentication token
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
example:
|
||||
error: Authentication required
|
||||
code: 401
|
||||
timestamp: 1705960800
|
||||
|
||||
Forbidden:
|
||||
description: Authenticated but insufficient permissions
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
example:
|
||||
error: Insufficient permissions
|
||||
code: 403
|
||||
timestamp: 1705960800
|
||||
|
||||
BadRequest:
|
||||
description: Invalid request parameters or body
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
example:
|
||||
error: Invalid request body
|
||||
code: 400
|
||||
timestamp: 1705960800
|
||||
|
||||
NotFound:
|
||||
description: Endpoint not found
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
example:
|
||||
error: Not Found
|
||||
code: 404
|
||||
timestamp: 1705960800
|
||||
|
||||
ServerError:
|
||||
description: Internal server error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
example:
|
||||
error: Internal server error
|
||||
code: 500
|
||||
timestamp: 1705960800
|
||||
|
||||
parameters:
|
||||
tokenQuery:
|
||||
name: token
|
||||
in: query
|
||||
description: JWT token (alternative to header/cookie)
|
||||
schema:
|
||||
type: string
|
||||
required: false
|
||||
|
||||
limitParam:
|
||||
name: limit
|
||||
in: query
|
||||
description: Maximum number of results to return
|
||||
schema:
|
||||
type: integer
|
||||
default: 100
|
||||
maximum: 100
|
||||
minimum: 1
|
||||
required: false
|
||||
|
||||
offsetParam:
|
||||
name: offset
|
||||
in: query
|
||||
description: Pagination offset
|
||||
schema:
|
||||
type: integer
|
||||
default: 0
|
||||
minimum: 0
|
||||
required: false
|
||||
|
||||
paths:
|
||||
/api/auth/login:
|
||||
post:
|
||||
tags:
|
||||
- Authentication
|
||||
summary: User login
|
||||
description: Authenticate user and receive JWT token for API access
|
||||
operationId: loginUser
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/LoginRequest'
|
||||
responses:
|
||||
'200':
|
||||
description: Login successful
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/LoginResponse'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
|
||||
/api/auth/verify:
|
||||
post:
|
||||
tags:
|
||||
- Authentication
|
||||
summary: Verify token
|
||||
description: Check if a JWT token is valid and retrieve user information
|
||||
operationId: verifyToken
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/VerifyTokenRequest'
|
||||
responses:
|
||||
'200':
|
||||
description: Token is valid
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/VerifyTokenResponse'
|
||||
'401':
|
||||
description: Token is invalid or expired
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/VerifyTokenError'
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
|
||||
/api/status:
|
||||
get:
|
||||
tags:
|
||||
- Server
|
||||
summary: Get server status
|
||||
description: Get current server status and version information
|
||||
operationId: getServerStatus
|
||||
security:
|
||||
- bearerAuth: []
|
||||
- queryToken: []
|
||||
- cookieToken: []
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/tokenQuery'
|
||||
responses:
|
||||
'200':
|
||||
description: Server status retrieved successfully
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ServerStatus'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'403':
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
|
||||
/api/players:
|
||||
get:
|
||||
tags:
|
||||
- Players
|
||||
summary: List online players
|
||||
description: Get list of currently online players on the server
|
||||
operationId: listPlayers
|
||||
security:
|
||||
- bearerAuth: []
|
||||
- queryToken: []
|
||||
- cookieToken: []
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/tokenQuery'
|
||||
- $ref: '#/components/parameters/limitParam'
|
||||
- $ref: '#/components/parameters/offsetParam'
|
||||
responses:
|
||||
'200':
|
||||
description: Players list retrieved successfully
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/PlayersResponse'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'403':
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
|
||||
/api/accounts/count:
|
||||
post:
|
||||
tags:
|
||||
- Statistics
|
||||
summary: Get total accounts count
|
||||
description: Get total number of registered accounts on the server
|
||||
operationId: getAccountsCount
|
||||
security:
|
||||
- bearerAuth: []
|
||||
- queryToken: []
|
||||
- cookieToken: []
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/tokenQuery'
|
||||
requestBody:
|
||||
required: false
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/AccountsCountRequest'
|
||||
responses:
|
||||
'200':
|
||||
description: Accounts count retrieved successfully
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/AccountsCountResponse'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'403':
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
|
||||
/api/characters/count:
|
||||
post:
|
||||
tags:
|
||||
- Statistics
|
||||
summary: Get total characters count
|
||||
description: Get total number of characters on the server
|
||||
operationId: getCharactersCount
|
||||
security:
|
||||
- bearerAuth: []
|
||||
- queryToken: []
|
||||
- cookieToken: []
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/tokenQuery'
|
||||
requestBody:
|
||||
required: false
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/CharactersCountRequest'
|
||||
responses:
|
||||
'200':
|
||||
description: Characters count retrieved successfully
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/CharactersCountResponse'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'403':
|
||||
$ref: '#/components/responses/Forbidden'
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
395
docs/grafana/darkflame-dashboard.json
Normal file
395
docs/grafana/darkflame-dashboard.json
Normal file
@@ -0,0 +1,395 @@
|
||||
{
|
||||
"title": "DarkflameServer",
|
||||
"uid": "darkflame-overview",
|
||||
"schemaVersion": 39,
|
||||
"version": 1,
|
||||
"editable": true,
|
||||
"time": {
|
||||
"from": "now-24h",
|
||||
"to": "now"
|
||||
},
|
||||
"refresh": "1m",
|
||||
"tags": [
|
||||
"darkflame"
|
||||
],
|
||||
"templating": {
|
||||
"list": [
|
||||
{
|
||||
"name": "datasource",
|
||||
"type": "datasource",
|
||||
"query": "prometheus",
|
||||
"label": "Prometheus"
|
||||
}
|
||||
]
|
||||
},
|
||||
"panels": [
|
||||
{
|
||||
"id": 1,
|
||||
"type": "stat",
|
||||
"title": "Servers",
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "${datasource}"
|
||||
},
|
||||
"gridPos": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 12,
|
||||
"h": 4
|
||||
},
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"mappings": [
|
||||
{
|
||||
"type": "value",
|
||||
"options": {
|
||||
"0": {
|
||||
"text": "Down",
|
||||
"color": "red"
|
||||
},
|
||||
"1": {
|
||||
"text": "Up",
|
||||
"color": "green"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"thresholds": {
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "red",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "green",
|
||||
"value": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"options": {
|
||||
"colorMode": "background",
|
||||
"graphMode": "none",
|
||||
"reduceOptions": {
|
||||
"calcs": [
|
||||
"lastNotNull"
|
||||
]
|
||||
}
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"refId": "A",
|
||||
"expr": "darkflame_master_connected",
|
||||
"legendFormat": "Master"
|
||||
},
|
||||
{
|
||||
"refId": "B",
|
||||
"expr": "darkflame_auth_up",
|
||||
"legendFormat": "Auth"
|
||||
},
|
||||
{
|
||||
"refId": "C",
|
||||
"expr": "darkflame_chat_up",
|
||||
"legendFormat": "Chat"
|
||||
},
|
||||
{
|
||||
"refId": "D",
|
||||
"expr": "darkflame_db_up",
|
||||
"legendFormat": "Database"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"type": "stat",
|
||||
"title": "Now",
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "${datasource}"
|
||||
},
|
||||
"gridPos": {
|
||||
"x": 12,
|
||||
"y": 0,
|
||||
"w": 12,
|
||||
"h": 4
|
||||
},
|
||||
"options": {
|
||||
"graphMode": "area",
|
||||
"reduceOptions": {
|
||||
"calcs": [
|
||||
"lastNotNull"
|
||||
]
|
||||
}
|
||||
},
|
||||
"fieldConfig": {
|
||||
"defaults": {},
|
||||
"overrides": []
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"refId": "A",
|
||||
"expr": "darkflame_players_online",
|
||||
"legendFormat": "Players"
|
||||
},
|
||||
{
|
||||
"refId": "B",
|
||||
"expr": "darkflame_world_instances",
|
||||
"legendFormat": "Worlds"
|
||||
},
|
||||
{
|
||||
"refId": "C",
|
||||
"expr": "darkflame_websocket_clients",
|
||||
"legendFormat": "Dashboard sockets"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"type": "timeseries",
|
||||
"title": "Players by zone",
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "${datasource}"
|
||||
},
|
||||
"gridPos": {
|
||||
"x": 0,
|
||||
"y": 4,
|
||||
"w": 12,
|
||||
"h": 8
|
||||
},
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"unit": "short",
|
||||
"custom": {
|
||||
"fillOpacity": 10,
|
||||
"stacking": {
|
||||
"mode": "normal"
|
||||
}
|
||||
}
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"refId": "A",
|
||||
"expr": "sum by (zone_name) (darkflame_zone_players)",
|
||||
"legendFormat": "{{zone_name}}"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"type": "timeseries",
|
||||
"title": "Instances by zone",
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "${datasource}"
|
||||
},
|
||||
"gridPos": {
|
||||
"x": 12,
|
||||
"y": 4,
|
||||
"w": 12,
|
||||
"h": 8
|
||||
},
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"unit": "short",
|
||||
"custom": {
|
||||
"fillOpacity": 10,
|
||||
"stacking": {
|
||||
"mode": "normal"
|
||||
}
|
||||
}
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"refId": "A",
|
||||
"expr": "sum by (zone_name) (darkflame_zone_instances)",
|
||||
"legendFormat": "{{zone_name}}"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"type": "timeseries",
|
||||
"title": "Memory by server",
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "${datasource}"
|
||||
},
|
||||
"gridPos": {
|
||||
"x": 0,
|
||||
"y": 12,
|
||||
"w": 12,
|
||||
"h": 8
|
||||
},
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"unit": "bytes",
|
||||
"custom": {
|
||||
"fillOpacity": 10,
|
||||
"stacking": {
|
||||
"mode": "normal"
|
||||
}
|
||||
}
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"refId": "A",
|
||||
"expr": "darkflame_server_memory_bytes",
|
||||
"legendFormat": "{{server}}"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"type": "timeseries",
|
||||
"title": "Chat messages per minute",
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "${datasource}"
|
||||
},
|
||||
"gridPos": {
|
||||
"x": 12,
|
||||
"y": 12,
|
||||
"w": 12,
|
||||
"h": 8
|
||||
},
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"unit": "short",
|
||||
"custom": {
|
||||
"fillOpacity": 10,
|
||||
"stacking": {
|
||||
"mode": "none"
|
||||
}
|
||||
}
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"refId": "A",
|
||||
"expr": "sum by (channel) (rate(darkflame_chat_messages_total[5m])) * 60",
|
||||
"legendFormat": "{{channel}}"
|
||||
},
|
||||
{
|
||||
"refId": "B",
|
||||
"expr": "sum(rate(darkflame_chat_messages_blocked_total[5m])) * 60",
|
||||
"legendFormat": "blocked"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"type": "bargauge",
|
||||
"title": "Moderation queues",
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "${datasource}"
|
||||
},
|
||||
"gridPos": {
|
||||
"x": 0,
|
||||
"y": 20,
|
||||
"w": 12,
|
||||
"h": 8
|
||||
},
|
||||
"options": {
|
||||
"orientation": "horizontal",
|
||||
"displayMode": "basic",
|
||||
"reduceOptions": {
|
||||
"calcs": [
|
||||
"lastNotNull"
|
||||
]
|
||||
}
|
||||
},
|
||||
"fieldConfig": {
|
||||
"defaults": {},
|
||||
"overrides": []
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"refId": "A",
|
||||
"expr": "darkflame_moderation_queue",
|
||||
"legendFormat": "{{queue}}"
|
||||
},
|
||||
{
|
||||
"refId": "B",
|
||||
"expr": "darkflame_active_strikes",
|
||||
"legendFormat": "active strikes"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"type": "timeseries",
|
||||
"title": "Coins today",
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "${datasource}"
|
||||
},
|
||||
"gridPos": {
|
||||
"x": 12,
|
||||
"y": 20,
|
||||
"w": 12,
|
||||
"h": 8
|
||||
},
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"unit": "short",
|
||||
"custom": {
|
||||
"fillOpacity": 10,
|
||||
"stacking": {
|
||||
"mode": "none"
|
||||
}
|
||||
}
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"refId": "A",
|
||||
"expr": "sum by (direction) (darkflame_economy_coins_today)",
|
||||
"legendFormat": "{{direction}}"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"type": "table",
|
||||
"title": "Scheduled tasks that failed last time",
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "${datasource}"
|
||||
},
|
||||
"gridPos": {
|
||||
"x": 0,
|
||||
"y": 28,
|
||||
"w": 24,
|
||||
"h": 6
|
||||
},
|
||||
"fieldConfig": {
|
||||
"defaults": {},
|
||||
"overrides": []
|
||||
},
|
||||
"options": {
|
||||
"showHeader": true
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"refId": "A",
|
||||
"expr": "darkflame_task_last_run_success == 0",
|
||||
"format": "table",
|
||||
"instant": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
16
docs/grafana/prometheus.yml
Normal file
16
docs/grafana/prometheus.yml
Normal file
@@ -0,0 +1,16 @@
|
||||
# Example Prometheus scrape config for the DarkflameServer dashboard's /metrics.
|
||||
# Switch metrics_enabled on (Settings > Dashboard > Metrics) first. Then either:
|
||||
# - set metrics_token on the Settings page and put the same value in the file below, or
|
||||
# - make an API token on the account page of an account with the metrics_view permission and use that.
|
||||
# The dashboard works the numbers out at most every metrics_cache_seconds (10), so scraping more often gains nothing.
|
||||
scrape_configs:
|
||||
- job_name: darkflame
|
||||
scrape_interval: 30s
|
||||
metrics_path: /metrics
|
||||
# https if the dashboard is behind a reverse proxy with TLS
|
||||
scheme: http
|
||||
authorization:
|
||||
type: Bearer
|
||||
credentials_file: /etc/prometheus/darkflame_metrics_token
|
||||
static_configs:
|
||||
- targets: ["127.0.0.1:2006"]
|
||||
Reference in New Issue
Block a user