Skip to content

Commit

Permalink
dns: per-zone metrics (#1432)
Browse files Browse the repository at this point in the history
* dns: save metrics per-zone too

* tsdb: add option to filter by more keys

* add per-zone graphs
  • Loading branch information
BeryJu authored Jan 12, 2025
1 parent 52d9cfd commit b3784fe
Show file tree
Hide file tree
Showing 10 changed files with 158 additions and 24 deletions.
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
.ONESHELL:
.SHELLFLAGS += -x -e
.PHONY: web
PWD = $(shell pwd)
UID = $(shell id -u)
GID = $(shell id -g)
Expand Down Expand Up @@ -33,6 +34,8 @@ run: internal/resources/macoui internal/resources/blocky internal/resources/tftp
go run ${GO_FLAGS} ${PWD} server

# Web
web: web-lint web-build

web-install:
cd ${PWD}/web
npm ci
Expand Down
5 changes: 3 additions & 2 deletions pkg/roles/dns/types/role.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ package types
import "time"

const (
KeyRole = "dns"
KeyZones = "zones"
KeyRole = "dns"
KeyZones = "zones"
KeyHandlerType = "handler"
)

const (
Expand Down
39 changes: 25 additions & 14 deletions pkg/roles/dns/zone.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,25 +25,22 @@ const (
)

type Zone struct {
inst roles.Instance
role *Role
inst roles.Instance
role *Role
log *zap.Logger
etcdKey string

h []Handler

records map[string]map[string]*Record
recordsWatchCtx context.CancelFunc
recordsSync sync.RWMutex

log *zap.Logger
Name string `json:"-"`

etcdKey string
Name string `json:"-"`
HandlerConfigs []map[string]interface{} `json:"handlerConfigs"`

h []Handler

recordsSync sync.RWMutex
DefaultTTL uint32 `json:"defaultTTL"`

Authoritative bool `json:"authoritative"`
Hook string `json:"hook"`
DefaultTTL uint32 `json:"defaultTTL"`
Authoritative bool `json:"authoritative"`
Hook string `json:"hook"`
}

func (z *Zone) Handlers() []Handler {
Expand All @@ -70,13 +67,27 @@ func (z *Zone) resolveUpdateMetrics(dur time.Duration, q *utils.DNSRequest, h Ha
map[string]interface{}{
"key": z.inst.KV().Key(
types.KeyRole,
types.KeyHandlerType,
h.Identifier(),
).String(),
"default": tsdbTypes.Metric{
ResetOnWrite: true,
},
},
))
go z.inst.DispatchEvent(tsdbTypes.EventTopicTSDBInc, roles.NewEvent(
context.Background(),
map[string]interface{}{
"key": z.inst.KV().Key(
types.KeyRole,
types.KeyZones,
z.Name,
).String(),
"default": tsdbTypes.Metric{
ResetOnWrite: true,
},
},
))
}
}

Expand Down
6 changes: 5 additions & 1 deletion pkg/roles/tsdb/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ func (r *Role) APIMetrics() usecase.Interactor {
if input.Category != "" {
pf = pf.Add(input.Category)
}
if len(input.ExtraKeys) > 0 {
pf = pf.Add(input.ExtraKeys...)
}
prefix := pf.Prefix(true).String()
rawMetrics, err := r.i.KV().Get(
ctx,
Expand Down Expand Up @@ -57,7 +60,8 @@ func (r *Role) APIMetrics() usecase.Interactor {
v.Value = value
}
output.Records = append(output.Records, types.APIMetricsRecord{
Keys: keyParts[:2],
// Remove node and timestamp from keys
Keys: keyParts[:len(keyParts)-2],
Time: time.Unix(int64(ts), 0),
Node: node,
Value: v.Value,
Expand Down
9 changes: 5 additions & 4 deletions pkg/roles/tsdb/types/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@ func (APIMetricsRole) Enum() []interface{} {
}

type APIMetricsGetInput struct {
Role APIMetricsRole `query:"role" required:"true"`
Category string `query:"category"`
Node string `query:"node"`
Since *time.Time `query:"since" description:"Optionally set a start time for which to return datapoints after"`
Role APIMetricsRole `query:"role" required:"true"`
Category string `query:"category"`
ExtraKeys []string `query:"extraKeys"`
Node string `query:"node"`
Since *time.Time `query:"since" description:"Optionally set a start time for which to return datapoints after"`
}

type APIMetricsRecord struct {
Expand Down
6 changes: 6 additions & 0 deletions schema.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1568,6 +1568,12 @@ paths:
name: category
schema:
type: string
- in: query
name: extraKeys
schema:
items:
type: string
type: array
- in: query
name: node
schema:
Expand Down
96 changes: 96 additions & 0 deletions web/src/pages/dns/DNSTableChart.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import { ChartData, ChartOptions } from "chart.js";
import { RolesTsdbApi, TypesAPIMetricsGetOutput, TypesAPIMetricsRole } from "gravity-api";

import { css } from "lit";
import { customElement, property } from "lit/decorators.js";

import { DEFAULT_CONFIG } from "../../api/Config";
import { AKChart } from "../../elements/charts/Chart";

@customElement("gravity-dns-zone-chart")
export class DNSTableChart extends AKChart<TypesAPIMetricsGetOutput> {
@property()
zone?: string;

static get styles() {
return super.styles.concat(css`
:host {
display: flex;
flex-direction: row;
justify-content: end;
}
.container {
width: 20rem;
height: 3rem;
}
`);
}

async apiRequest(): Promise<TypesAPIMetricsGetOutput> {
return new RolesTsdbApi(DEFAULT_CONFIG).tsdbGetMetrics({
role: TypesAPIMetricsRole.Dns,
category: "zones",
extraKeys: [this.zone || ""],
});
}

getChartType(): string {
return "line";
}

firstUpdated(): void {
super.firstUpdated();
if (!this.parentElement) {
return;
}
this.parentElement.style.width = "28rem";
this.parentElement.style.padding = "0";
}

getOptions(): ChartOptions {
return {
maintainAspectRatio: false,
plugins: {
legend: {
display: false,
},
},
layout: {
padding: 0,
},
scales: {
x: {
type: "time",
display: false,
},
y: {
type: "linear",
display: false,
},
},
} as ChartOptions;
}

getChartData(data: TypesAPIMetricsGetOutput): ChartData {
const chartData: ChartData = {
datasets: [],
};
chartData.datasets.push({
backgroundColor: "rgba(0,0,0,0)",
borderColor: "#3873e0",
spanGaps: true,
fill: "origin",
cubicInterpolationMode: "monotone",
tension: 0.4,
pointStyle: false,
data:
data.records?.map((record) => {
return {
x: record.time.getTime(),
y: record.value,
};
}) || [],
});
return chartData;
}
}
3 changes: 3 additions & 0 deletions web/src/pages/dns/DNSZonesPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import "../../elements/forms/ModalForm";
import { PaginatedResponse, TableColumn } from "../../elements/table/Table";
import { TablePage } from "../../elements/table/TablePage";
import { PaginationWrapper } from "../../utils";
import "./DNSTableChart";
import "./DNSZoneForm";
import "./wizard/DNSZoneWizard";

Expand Down Expand Up @@ -47,6 +48,7 @@ export class DNSZonesPage extends TablePage<DnsAPIZone> {
new TableColumn("Zone"),
new TableColumn("Records"),
new TableColumn("Authoritative"),
new TableColumn(""),
new TableColumn("Actions"),
];
}
Expand All @@ -58,6 +60,7 @@ export class DNSZonesPage extends TablePage<DnsAPIZone> {
</a>`,
html`${item.recordCount}`,
html`${item.authoritative ? "Yes" : "No"}`,
html`<gravity-dns-zone-chart zone=${item.name}></gravity-dns-zone-chart>`,
html`<ak-forms-modal>
<span slot="submit"> ${"Update"} </span>
<span slot="header"> ${"Update Zone"} </span>
Expand Down
2 changes: 1 addition & 1 deletion web/src/pages/dns/wizard/ZoneImportWizardPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import { customElement } from "@lit/reactive-element/decorators/custom-element.j
import { TemplateResult, html } from "lit";

import { DEFAULT_CONFIG } from "../../../api/Config";
import { convertToTitle } from "../../../common/utils";
import { KeyUnknown } from "../../../elements/forms/Form";
import "../../../elements/forms/FormGroup";
import "../../../elements/forms/HorizontalFormElement";
import { WizardFormPage } from "../../../elements/wizard/WizardFormPage";
import { convertToTitle } from "../../../common/utils";

@customElement("gravity-dns-wizard-import")
export class ZoneImportWizardPage extends WizardFormPage {
Expand Down
13 changes: 11 additions & 2 deletions web/src/pages/overview/charts/DNSRequestsChart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ import { AKChart } from "../../../elements/charts/Chart";
@customElement("gravity-overview-charts-dns-requests")
export class DNSRequestsChart extends AKChart<TypesAPIMetricsGetOutput> {
apiRequest(): Promise<TypesAPIMetricsGetOutput> {
return new RolesTsdbApi(DEFAULT_CONFIG).tsdbGetMetrics({ role: TypesAPIMetricsRole.Dns });
return new RolesTsdbApi(DEFAULT_CONFIG).tsdbGetMetrics({
role: TypesAPIMetricsRole.Dns,
category: "handler",
});
}

getChartType(): string {
Expand All @@ -23,7 +26,13 @@ export class DNSRequestsChart extends AKChart<TypesAPIMetricsGetOutput> {
datasets: [],
};
groupBy(data.records || [], (record) => record.node).forEach(([node, records]) => {
groupBy(records, (record) => record.keys![1]).forEach(([handler, records]) => {
groupBy(records, (record) => {
// TODO: Remove in the future
if (record.keys?.length === 3) {
return record.keys![1] && record.keys![2];
}
return record.keys![1];
}).forEach(([handler, records]) => {
const background = getColorFromString(handler);
background.a = 0.3;
chartData.datasets.push({
Expand Down

0 comments on commit b3784fe

Please sign in to comment.