mirror of
https://github.com/prometheus-community/windows_exporter.git
synced 2026-02-08 05:56:37 +00:00
Compare commits
50 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5e7462a70e | ||
|
|
e8864c766e | ||
|
|
07fff6afc2 | ||
|
|
083537a96a | ||
|
|
6aa0ac5706 | ||
|
|
7d2d7f3d1c | ||
|
|
f8c298e038 | ||
|
|
4e9fa4fd8e | ||
|
|
d8524c505b | ||
|
|
ca6eb75685 | ||
|
|
5631166075 | ||
|
|
1d027579d2 | ||
|
|
23e1a86aa7 | ||
|
|
f8b8b2c546 | ||
|
|
d78230f67b | ||
|
|
f7426e9fad | ||
|
|
fdec95bc99 | ||
|
|
75ae769b6e | ||
|
|
4add010b8d | ||
|
|
7530e7b400 | ||
|
|
9473265ffa | ||
|
|
0ec4e9d90f | ||
|
|
7876a465ca | ||
|
|
f9361bb684 | ||
|
|
f5b9ba35d0 | ||
|
|
7c178e5ced | ||
|
|
134bae514d | ||
|
|
a4beb4c187 | ||
|
|
884cac808a | ||
|
|
117ba941df | ||
|
|
8d61595607 | ||
|
|
68f5c61de8 | ||
|
|
ca5124fdf9 | ||
|
|
e2b48497f4 | ||
|
|
b1eaf00e74 | ||
|
|
34da140f87 | ||
|
|
7a3a978d79 | ||
|
|
e9b8f82b2c | ||
|
|
b0a1a38829 | ||
|
|
f77bdcfa09 | ||
|
|
2fb5b89d92 | ||
|
|
65c8fa4304 | ||
|
|
8f7031861a | ||
|
|
a78c707f47 | ||
|
|
eb1b1ccb54 | ||
|
|
8447758db5 | ||
|
|
05091643c6 | ||
|
|
76e73487e4 | ||
|
|
9a2ec21278 | ||
|
|
44b435e7d4 |
7
.github/workflows/lint.yml
vendored
7
.github/workflows/lint.yml
vendored
@@ -23,6 +23,7 @@ on:
|
||||
- master
|
||||
|
||||
env:
|
||||
GO_VER: '^1.21.1'
|
||||
PROMU_VER: '0.14.0'
|
||||
PROMTOOL_VER: '2.43.0'
|
||||
|
||||
@@ -33,7 +34,7 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: '^1.20.2'
|
||||
go-version: ${{ env.GO_VER }}
|
||||
|
||||
- name: Test
|
||||
run: make test
|
||||
@@ -57,7 +58,7 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: '^1.20.2'
|
||||
go-version: ${{ env.GO_VER }}
|
||||
|
||||
- name: Install promtool
|
||||
run: |
|
||||
@@ -89,7 +90,7 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: '^1.20.2'
|
||||
go-version: ${{ env.GO_VER }}
|
||||
|
||||
- name: golangci-lint
|
||||
uses: golangci/golangci-lint-action@v3
|
||||
|
||||
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@@ -25,7 +25,7 @@ jobs:
|
||||
|
||||
- uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: '^1.20.2'
|
||||
go-version: '^1.21.1'
|
||||
|
||||
- name: Install Build deps
|
||||
run: |
|
||||
|
||||
2
Makefile
2
Makefile
@@ -20,7 +20,7 @@ test:
|
||||
go test -v ./...
|
||||
|
||||
bench:
|
||||
go test -v -bench='benchmark(cpu|logicaldisk|logon|memory|net|process|service|system|tcp|time)collector' ./...
|
||||
go test -v -bench='benchmark(cpu|logicaldisk|physicaldisk|logon|memory|net|process|service|system|tcp|time)collector' ./...
|
||||
|
||||
lint:
|
||||
golangci-lint -c .golangci.yaml run
|
||||
|
||||
@@ -59,6 +59,7 @@ type ADCollector struct {
|
||||
LdapSearchesTotal *prometheus.Desc
|
||||
LdapUdpOperationsTotal *prometheus.Desc
|
||||
LdapWritesTotal *prometheus.Desc
|
||||
LdapClientSessions *prometheus.Desc
|
||||
LinkValuesCleanedTotal *prometheus.Desc
|
||||
PhantomObjectsCleanedTotal *prometheus.Desc
|
||||
PhantomObjectsVisitedTotal *prometheus.Desc
|
||||
@@ -343,6 +344,12 @@ func newADCollector(logger log.Logger) (Collector, error) {
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
LdapClientSessions: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "ldap_client_sessions"),
|
||||
"This is the number of sessions opened by LDAP clients at the time the data is taken. This is helpful in determining LDAP client activity and if the DC is able to handle the load. Of course, spikes during normal periods of authentication — such as first thing in the morning — are not necessarily a problem, but long sustained periods of high values indicate an overworked DC.",
|
||||
nil,
|
||||
nil,
|
||||
),
|
||||
LinkValuesCleanedTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "link_values_cleaned_total"),
|
||||
"",
|
||||
@@ -1190,6 +1197,11 @@ func (c *ADCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, er
|
||||
prometheus.CounterValue,
|
||||
float64(dst[0].LDAPWritesPersec),
|
||||
)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.LdapClientSessions,
|
||||
prometheus.GaugeValue,
|
||||
float64(dst[0].LDAPClientSessions),
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.LinkValuesCleanedTotal,
|
||||
|
||||
@@ -59,16 +59,18 @@ type HyperVCollector struct {
|
||||
HostLPTotalRunTimePercent *prometheus.Desc
|
||||
|
||||
// Win32_PerfRawData_HvStats_HyperVHypervisorRootVirtualProcessor
|
||||
HostGuestRunTime *prometheus.Desc
|
||||
HostHypervisorRunTime *prometheus.Desc
|
||||
HostRemoteRunTime *prometheus.Desc
|
||||
HostTotalRunTime *prometheus.Desc
|
||||
HostGuestRunTime *prometheus.Desc
|
||||
HostHypervisorRunTime *prometheus.Desc
|
||||
HostRemoteRunTime *prometheus.Desc
|
||||
HostTotalRunTime *prometheus.Desc
|
||||
HostCPUWaitTimePerDispatch *prometheus.Desc
|
||||
|
||||
// Win32_PerfRawData_HvStats_HyperVHypervisorVirtualProcessor
|
||||
VMGuestRunTime *prometheus.Desc
|
||||
VMHypervisorRunTime *prometheus.Desc
|
||||
VMRemoteRunTime *prometheus.Desc
|
||||
VMTotalRunTime *prometheus.Desc
|
||||
VMGuestRunTime *prometheus.Desc
|
||||
VMHypervisorRunTime *prometheus.Desc
|
||||
VMRemoteRunTime *prometheus.Desc
|
||||
VMTotalRunTime *prometheus.Desc
|
||||
VMCPUWaitTimePerDispatch *prometheus.Desc
|
||||
|
||||
// Win32_PerfRawData_NvspSwitchStats_HyperVVirtualSwitch
|
||||
BroadcastPacketsReceived *prometheus.Desc
|
||||
@@ -362,6 +364,12 @@ func newHyperVCollector(logger log.Logger) (Collector, error) {
|
||||
[]string{"core"},
|
||||
nil,
|
||||
),
|
||||
HostCPUWaitTimePerDispatch: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, buildSubsystemName("host_cpu"), "wait_time_per_dispatch_total"),
|
||||
"Time in nanoseconds waiting for a virtual processor to be dispatched onto a logical processor",
|
||||
[]string{"core"},
|
||||
nil,
|
||||
),
|
||||
|
||||
//
|
||||
|
||||
@@ -389,6 +397,12 @@ func newHyperVCollector(logger log.Logger) (Collector, error) {
|
||||
[]string{"vm", "core"},
|
||||
nil,
|
||||
),
|
||||
VMCPUWaitTimePerDispatch: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, buildSubsystemName("vm_cpu"), "wait_time_per_dispatch_total"),
|
||||
"Time in nanoseconds waiting for a virtual processor to be dispatched onto a logical processor",
|
||||
[]string{"vm", "core"},
|
||||
nil,
|
||||
),
|
||||
|
||||
//
|
||||
BroadcastPacketsReceived: prometheus.NewDesc(
|
||||
@@ -1093,6 +1107,7 @@ type Win32_PerfRawData_HvStats_HyperVHypervisorRootVirtualProcessor struct {
|
||||
PercentHypervisorRunTime uint64
|
||||
PercentRemoteRunTime uint64
|
||||
PercentTotalRunTime uint64
|
||||
CPUWaitTimePerDispatch uint64
|
||||
}
|
||||
|
||||
func (c *HyperVCollector) collectHostCpuUsage(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
@@ -1142,6 +1157,12 @@ func (c *HyperVCollector) collectHostCpuUsage(ch chan<- prometheus.Metric) (*pro
|
||||
coreId,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.HostCPUWaitTimePerDispatch,
|
||||
prometheus.CounterValue,
|
||||
float64(obj.CPUWaitTimePerDispatch),
|
||||
coreId,
|
||||
)
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
@@ -1154,6 +1175,7 @@ type Win32_PerfRawData_HvStats_HyperVHypervisorVirtualProcessor struct {
|
||||
PercentHypervisorRunTime uint64
|
||||
PercentRemoteRunTime uint64
|
||||
PercentTotalRunTime uint64
|
||||
CPUWaitTimePerDispatch uint64
|
||||
}
|
||||
|
||||
func (c *HyperVCollector) collectVmCpuUsage(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
@@ -1209,6 +1231,13 @@ func (c *HyperVCollector) collectVmCpuUsage(ch chan<- prometheus.Metric) (*prome
|
||||
vmName, coreId,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.VMCPUWaitTimePerDispatch,
|
||||
prometheus.CounterValue,
|
||||
float64(obj.CPUWaitTimePerDispatch),
|
||||
vmName, coreId,
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
|
||||
@@ -220,7 +220,7 @@ type IISCollector struct {
|
||||
}
|
||||
|
||||
func newIISCollectorFlags(app *kingpin.Application) {
|
||||
oldSiteInclude = app.Flag(FlagIISSiteOldInclude, "DEPRECATED: Use --collector.iis.site-include").Default(".+").Hidden().String()
|
||||
oldSiteInclude = app.Flag(FlagIISSiteOldInclude, "DEPRECATED: Use --collector.iis.site-include").Hidden().String()
|
||||
oldSiteExclude = app.Flag(FlagIISSiteOldExclude, "DEPRECATED: Use --collector.iis.site-exclude").Hidden().String()
|
||||
oldAppInclude = app.Flag(FlagIISAppOldInclude, "DEPRECATED: Use --collector.iis.app-include").Hidden().String()
|
||||
oldAppExclude = app.Flag(FlagIISAppOldExclude, "DEPRECATED: Use --collector.iis.app-exclude").Hidden().String()
|
||||
|
||||
@@ -288,6 +288,14 @@ var collectors = []collectorInit{
|
||||
return []string{"Paging File"}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "physical_disk",
|
||||
flags: newPhysicalDiskCollectorFlags,
|
||||
builder: NewPhysicalDiskCollector,
|
||||
perfCounterFunc: func(_ log.Logger) []string {
|
||||
return []string{"PhysicalDisk"}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "process",
|
||||
flags: newProcessCollectorFlags,
|
||||
|
||||
298
collector/physical_disk.go
Normal file
298
collector/physical_disk.go
Normal file
@@ -0,0 +1,298 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package collector
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
const (
|
||||
FlagPhysicalDiskExclude = "collector.physical_disk.disk-exclude"
|
||||
FlagPhysicalDiskInclude = "collector.physical_disk.disk-include"
|
||||
)
|
||||
|
||||
var (
|
||||
diskInclude *string
|
||||
diskExclude *string
|
||||
|
||||
diskIncludeSet bool
|
||||
diskExcludeSet bool
|
||||
)
|
||||
|
||||
// A PhysicalDiskCollector is a Prometheus collector for perflib PhysicalDisk metrics
|
||||
type PhysicalDiskCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
RequestsQueued *prometheus.Desc
|
||||
ReadBytesTotal *prometheus.Desc
|
||||
ReadsTotal *prometheus.Desc
|
||||
WriteBytesTotal *prometheus.Desc
|
||||
WritesTotal *prometheus.Desc
|
||||
ReadTime *prometheus.Desc
|
||||
WriteTime *prometheus.Desc
|
||||
IdleTime *prometheus.Desc
|
||||
SplitIOs *prometheus.Desc
|
||||
ReadLatency *prometheus.Desc
|
||||
WriteLatency *prometheus.Desc
|
||||
ReadWriteLatency *prometheus.Desc
|
||||
|
||||
diskIncludePattern *regexp.Regexp
|
||||
diskExcludePattern *regexp.Regexp
|
||||
}
|
||||
|
||||
// newPhysicalDiskCollectorFlags ...
|
||||
func newPhysicalDiskCollectorFlags(app *kingpin.Application) {
|
||||
diskInclude = app.Flag(
|
||||
FlagPhysicalDiskInclude,
|
||||
"Regexp of disks to include. Disk number must both match include and not match exclude to be included.",
|
||||
).Default(".+").PreAction(func(c *kingpin.ParseContext) error {
|
||||
diskIncludeSet = true
|
||||
return nil
|
||||
}).String()
|
||||
|
||||
diskExclude = app.Flag(
|
||||
FlagPhysicalDiskExclude,
|
||||
"Regexp of disks to exclude. Disk number must both match include and not match exclude to be included.",
|
||||
).Default("").PreAction(func(c *kingpin.ParseContext) error {
|
||||
diskExcludeSet = true
|
||||
return nil
|
||||
}).String()
|
||||
}
|
||||
|
||||
// NewPhysicalDiskCollector ...
|
||||
func NewPhysicalDiskCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "physical_disk"
|
||||
logger = log.With(logger, "collector", subsystem)
|
||||
|
||||
return &PhysicalDiskCollector{
|
||||
logger: logger,
|
||||
|
||||
RequestsQueued: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "requests_queued"),
|
||||
"The number of requests queued to the disk (PhysicalDisk.CurrentDiskQueueLength)",
|
||||
[]string{"disk"},
|
||||
nil,
|
||||
),
|
||||
|
||||
ReadBytesTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "read_bytes_total"),
|
||||
"The number of bytes transferred from the disk during read operations (PhysicalDisk.DiskReadBytesPerSec)",
|
||||
[]string{"disk"},
|
||||
nil,
|
||||
),
|
||||
|
||||
ReadsTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "reads_total"),
|
||||
"The number of read operations on the disk (PhysicalDisk.DiskReadsPerSec)",
|
||||
[]string{"disk"},
|
||||
nil,
|
||||
),
|
||||
|
||||
WriteBytesTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "write_bytes_total"),
|
||||
"The number of bytes transferred to the disk during write operations (PhysicalDisk.DiskWriteBytesPerSec)",
|
||||
[]string{"disk"},
|
||||
nil,
|
||||
),
|
||||
|
||||
WritesTotal: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "writes_total"),
|
||||
"The number of write operations on the disk (PhysicalDisk.DiskWritesPerSec)",
|
||||
[]string{"disk"},
|
||||
nil,
|
||||
),
|
||||
|
||||
ReadTime: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "read_seconds_total"),
|
||||
"Seconds that the disk was busy servicing read requests (PhysicalDisk.PercentDiskReadTime)",
|
||||
[]string{"disk"},
|
||||
nil,
|
||||
),
|
||||
|
||||
WriteTime: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "write_seconds_total"),
|
||||
"Seconds that the disk was busy servicing write requests (PhysicalDisk.PercentDiskWriteTime)",
|
||||
[]string{"disk"},
|
||||
nil,
|
||||
),
|
||||
|
||||
IdleTime: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "idle_seconds_total"),
|
||||
"Seconds that the disk was idle (PhysicalDisk.PercentIdleTime)",
|
||||
[]string{"disk"},
|
||||
nil,
|
||||
),
|
||||
|
||||
SplitIOs: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "split_ios_total"),
|
||||
"The number of I/Os to the disk were split into multiple I/Os (PhysicalDisk.SplitIOPerSec)",
|
||||
[]string{"disk"},
|
||||
nil,
|
||||
),
|
||||
|
||||
ReadLatency: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "read_latency_seconds_total"),
|
||||
"Shows the average time, in seconds, of a read operation from the disk (PhysicalDisk.AvgDiskSecPerRead)",
|
||||
[]string{"disk"},
|
||||
nil,
|
||||
),
|
||||
|
||||
WriteLatency: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "write_latency_seconds_total"),
|
||||
"Shows the average time, in seconds, of a write operation to the disk (PhysicalDisk.AvgDiskSecPerWrite)",
|
||||
[]string{"disk"},
|
||||
nil,
|
||||
),
|
||||
|
||||
ReadWriteLatency: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, subsystem, "read_write_latency_seconds_total"),
|
||||
"Shows the time, in seconds, of the average disk transfer (PhysicalDisk.AvgDiskSecPerTransfer)",
|
||||
[]string{"disk"},
|
||||
nil,
|
||||
),
|
||||
|
||||
diskIncludePattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *diskInclude)),
|
||||
diskExcludePattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *diskExclude)),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Collect sends the metric values for each metric
|
||||
// to the provided prometheus Metric channel.
|
||||
func (c *PhysicalDiskCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
if desc, err := c.collect(ctx, ch); err != nil {
|
||||
_ = level.Error(c.logger).Log("failed collecting physical_disk metrics", "desc", desc, "err", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Win32_PerfRawData_PerfDisk_PhysicalDisk docs:
|
||||
// - https://docs.microsoft.com/en-us/previous-versions/aa394308(v=vs.85) - Win32_PerfRawData_PerfDisk_PhysicalDisk class
|
||||
type PhysicalDisk struct {
|
||||
Name string
|
||||
CurrentDiskQueueLength float64 `perflib:"Current Disk Queue Length"`
|
||||
DiskReadBytesPerSec float64 `perflib:"Disk Read Bytes/sec"`
|
||||
DiskReadsPerSec float64 `perflib:"Disk Reads/sec"`
|
||||
DiskWriteBytesPerSec float64 `perflib:"Disk Write Bytes/sec"`
|
||||
DiskWritesPerSec float64 `perflib:"Disk Writes/sec"`
|
||||
PercentDiskReadTime float64 `perflib:"% Disk Read Time"`
|
||||
PercentDiskWriteTime float64 `perflib:"% Disk Write Time"`
|
||||
PercentIdleTime float64 `perflib:"% Idle Time"`
|
||||
SplitIOPerSec float64 `perflib:"Split IO/Sec"`
|
||||
AvgDiskSecPerRead float64 `perflib:"Avg. Disk sec/Read"`
|
||||
AvgDiskSecPerWrite float64 `perflib:"Avg. Disk sec/Write"`
|
||||
AvgDiskSecPerTransfer float64 `perflib:"Avg. Disk sec/Transfer"`
|
||||
}
|
||||
|
||||
func (c *PhysicalDiskCollector) collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
|
||||
var dst []PhysicalDisk
|
||||
if err := unmarshalObject(ctx.perfObjects["PhysicalDisk"], &dst, c.logger); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, disk := range dst {
|
||||
if disk.Name == "_Total" ||
|
||||
c.diskExcludePattern.MatchString(disk.Name) ||
|
||||
!c.diskIncludePattern.MatchString(disk.Name) {
|
||||
continue
|
||||
}
|
||||
|
||||
// Parse physical disk number from disk.Name. Mountpoint information is
|
||||
// sometimes included, e.g. "1 C:".
|
||||
disk_number, _, _ := strings.Cut(disk.Name, " ")
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.RequestsQueued,
|
||||
prometheus.GaugeValue,
|
||||
disk.CurrentDiskQueueLength,
|
||||
disk_number,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ReadBytesTotal,
|
||||
prometheus.CounterValue,
|
||||
disk.DiskReadBytesPerSec,
|
||||
disk_number,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ReadsTotal,
|
||||
prometheus.CounterValue,
|
||||
disk.DiskReadsPerSec,
|
||||
disk_number,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.WriteBytesTotal,
|
||||
prometheus.CounterValue,
|
||||
disk.DiskWriteBytesPerSec,
|
||||
disk_number,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.WritesTotal,
|
||||
prometheus.CounterValue,
|
||||
disk.DiskWritesPerSec,
|
||||
disk_number,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ReadTime,
|
||||
prometheus.CounterValue,
|
||||
disk.PercentDiskReadTime,
|
||||
disk_number,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.WriteTime,
|
||||
prometheus.CounterValue,
|
||||
disk.PercentDiskWriteTime,
|
||||
disk_number,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.IdleTime,
|
||||
prometheus.CounterValue,
|
||||
disk.PercentIdleTime,
|
||||
disk_number,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.SplitIOs,
|
||||
prometheus.CounterValue,
|
||||
disk.SplitIOPerSec,
|
||||
disk_number,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ReadLatency,
|
||||
prometheus.CounterValue,
|
||||
disk.AvgDiskSecPerRead*ticksToSecondsScaleFactor,
|
||||
disk_number,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.WriteLatency,
|
||||
prometheus.CounterValue,
|
||||
disk.AvgDiskSecPerWrite*ticksToSecondsScaleFactor,
|
||||
disk_number,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.ReadWriteLatency,
|
||||
prometheus.CounterValue,
|
||||
disk.AvgDiskSecPerTransfer*ticksToSecondsScaleFactor,
|
||||
disk_number,
|
||||
)
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
@@ -19,7 +19,6 @@ package collector
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
@@ -37,11 +36,13 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
FlagTextFileDirectory = "collector.textfile.directory"
|
||||
FlagTextFileDirectory = "collector.textfile.directory"
|
||||
FlagTextFileDirectories = "collector.textfile.directories"
|
||||
)
|
||||
|
||||
var (
|
||||
textFileDirectory *string
|
||||
textFileDirectory *string
|
||||
textFileDirectories *string
|
||||
|
||||
mtimeDesc = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(Namespace, "textfile", "mtime_seconds"),
|
||||
@@ -54,7 +55,7 @@ var (
|
||||
type textFileCollector struct {
|
||||
logger log.Logger
|
||||
|
||||
path string
|
||||
directories string
|
||||
// Only set for testing to get predictable output.
|
||||
mtime *float64
|
||||
}
|
||||
@@ -63,17 +64,27 @@ type textFileCollector struct {
|
||||
func newTextFileCollectorFlags(app *kingpin.Application) {
|
||||
textFileDirectory = app.Flag(
|
||||
FlagTextFileDirectory,
|
||||
"Directory to read text files with metrics from.",
|
||||
).Default(getDefaultPath()).String()
|
||||
"DEPRECATED: Use --collector.textfile.directories",
|
||||
).Default("").Hidden().String()
|
||||
textFileDirectories = app.Flag(
|
||||
FlagTextFileDirectories,
|
||||
"Directory or Directories to read text files with metrics from.",
|
||||
).Default("").String()
|
||||
}
|
||||
|
||||
// newTextFileCollector returns a new Collector exposing metrics read from files
|
||||
// in the given textfile directory.
|
||||
func newTextFileCollector(logger log.Logger) (Collector, error) {
|
||||
const subsystem = "textfile"
|
||||
directories := getDefaultPath()
|
||||
if *textFileDirectory != "" || *textFileDirectories != "" {
|
||||
directories = *textFileDirectory + "," + *textFileDirectories
|
||||
directories = strings.Trim(directories, ",")
|
||||
}
|
||||
_ = level.Info(logger).Log("msg", fmt.Sprintf("textfile collector directories: %s", directories))
|
||||
return &textFileCollector{
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
path: *textFileDirectory,
|
||||
logger: log.With(logger, "collector", subsystem),
|
||||
directories: directories,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -250,89 +261,55 @@ func (cr carriageReturnFilteringReader) Read(p []byte) (int, error) {
|
||||
|
||||
// Update implements the Collector interface.
|
||||
func (c *textFileCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error {
|
||||
error := 0.0
|
||||
mtimes := map[string]time.Time{}
|
||||
|
||||
// Iterate over files and accumulate their metrics.
|
||||
files, err := ioutil.ReadDir(c.path)
|
||||
if err != nil && c.path != "" {
|
||||
_ = level.Error(c.logger).Log("msg", fmt.Sprintf("Error reading textfile collector directory %q", c.path), "err", err)
|
||||
error = 1.0
|
||||
}
|
||||
|
||||
errorMetric := 0.0
|
||||
var mtimes = map[string]time.Time{}
|
||||
// Create empty metricFamily slice here and append parsedFamilies to it inside the loop.
|
||||
// Once loop is complete, raise error if any duplicates are present.
|
||||
// This will ensure that duplicate metrics are correctly detected between multiple .prom files.
|
||||
var metricFamilies = []*dto.MetricFamily{}
|
||||
fileLoop:
|
||||
for _, f := range files {
|
||||
if !strings.HasSuffix(f.Name(), ".prom") {
|
||||
continue
|
||||
}
|
||||
path := filepath.Join(c.path, f.Name())
|
||||
_ = level.Debug(c.logger).Log("msg", fmt.Sprintf("Processing file %q", path))
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
_ = level.Error(c.logger).Log("msg", fmt.Sprintf("Error opening %q: %v", path, err))
|
||||
error = 1.0
|
||||
continue
|
||||
}
|
||||
var parser expfmt.TextParser
|
||||
r, encoding := utfbom.Skip(carriageReturnFilteringReader{r: file})
|
||||
if err = checkBOM(encoding); err != nil {
|
||||
_ = level.Error(c.logger).Log("msg", fmt.Sprintf("Invalid file encoding detected in %s: %s - file must be UTF8", path, err.Error()))
|
||||
error = 1.0
|
||||
continue
|
||||
}
|
||||
parsedFamilies, err := parser.TextToMetricFamilies(r)
|
||||
closeErr := file.Close()
|
||||
if closeErr != nil {
|
||||
_ = level.Warn(c.logger).Log("msg", fmt.Sprintf("Error closing file"), "err", err)
|
||||
}
|
||||
if err != nil {
|
||||
_ = level.Error(c.logger).Log("msg", fmt.Sprintf("Error parsing %q: %v", path, err))
|
||||
error = 1.0
|
||||
continue
|
||||
}
|
||||
|
||||
// Use temporary array to check for duplicates
|
||||
var families_array []*dto.MetricFamily
|
||||
|
||||
for _, mf := range parsedFamilies {
|
||||
families_array = append(families_array, mf)
|
||||
for _, m := range mf.Metric {
|
||||
if m.TimestampMs != nil {
|
||||
_ = level.Error(c.logger).Log("msg", fmt.Sprintf("Textfile %q contains unsupported client-side timestamps, skipping entire file", path))
|
||||
error = 1.0
|
||||
continue fileLoop
|
||||
// Iterate over files and accumulate their metrics.
|
||||
for _, directory := range strings.Split(c.directories, ",") {
|
||||
err := filepath.WalkDir(directory, func(path string, dirEntry os.DirEntry, err error) error {
|
||||
if err != nil {
|
||||
_ = level.Error(c.logger).Log("msg", fmt.Sprintf("Error reading directory: %s", path), "err", err)
|
||||
errorMetric = 1.0
|
||||
return nil
|
||||
}
|
||||
if !dirEntry.IsDir() && strings.HasSuffix(dirEntry.Name(), ".prom") {
|
||||
_ = level.Debug(c.logger).Log("msg", fmt.Sprintf("Processing file: %s", path))
|
||||
families_array, err := scrapeFile(path, c.logger)
|
||||
if err != nil {
|
||||
_ = level.Error(c.logger).Log("msg", fmt.Sprintf("Error scraping file: %q. Skip File.", path), "err", err)
|
||||
errorMetric = 1.0
|
||||
return nil
|
||||
}
|
||||
fileInfo, err := os.Stat(path)
|
||||
if err != nil {
|
||||
_ = level.Error(c.logger).Log("msg", fmt.Sprintf("Error reading file info: %q. Skip File.", path), "err", err)
|
||||
errorMetric = 1.0
|
||||
return nil
|
||||
}
|
||||
if _, hasName := mtimes[fileInfo.Name()]; hasName {
|
||||
_ = level.Error(c.logger).Log("msg", fmt.Sprintf("Duplicate filename detected: %q. Skip File.", path))
|
||||
errorMetric = 1.0
|
||||
return nil
|
||||
}
|
||||
mtimes[fileInfo.Name()] = fileInfo.ModTime()
|
||||
metricFamilies = append(metricFamilies, families_array...)
|
||||
}
|
||||
if mf.Help == nil {
|
||||
help := fmt.Sprintf("Metric read from %s", path)
|
||||
mf.Help = &help
|
||||
}
|
||||
}
|
||||
|
||||
// If duplicate metrics are detected in a *single* file, skip processing of file metrics
|
||||
if duplicateMetricEntry(families_array) {
|
||||
_ = level.Error(c.logger).Log("msg", fmt.Sprintf("Duplicate metrics detected in file %s. Skipping file processing.", f.Name()))
|
||||
error = 1.0
|
||||
continue
|
||||
}
|
||||
|
||||
// Only set this once it has been parsed and validated, so that
|
||||
// a failure does not appear fresh.
|
||||
mtimes[f.Name()] = f.ModTime()
|
||||
|
||||
for _, metricFamily := range parsedFamilies {
|
||||
metricFamilies = append(metricFamilies, metricFamily)
|
||||
return nil
|
||||
})
|
||||
if err != nil && directory != "" {
|
||||
_ = level.Error(c.logger).Log("msg", fmt.Sprintf("Error reading textfile collector directory: %s", c.directories), "err", err)
|
||||
errorMetric = 1.0
|
||||
}
|
||||
}
|
||||
|
||||
// If duplicates are detected across *multiple* files, return error.
|
||||
if duplicateMetricEntry(metricFamilies) {
|
||||
_ = level.Error(c.logger).Log("msg", "Duplicate metrics detected across multiple files")
|
||||
error = 1.0
|
||||
errorMetric = 1.0
|
||||
} else {
|
||||
for _, mf := range metricFamilies {
|
||||
c.convertMetricFamily(mf, ch)
|
||||
@@ -340,7 +317,6 @@ fileLoop:
|
||||
}
|
||||
|
||||
c.exportMTimes(mtimes, ch)
|
||||
|
||||
// Export if there were errors.
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
prometheus.NewDesc(
|
||||
@@ -348,11 +324,53 @@ fileLoop:
|
||||
"1 if there was an error opening or reading a file, 0 otherwise",
|
||||
nil, nil,
|
||||
),
|
||||
prometheus.GaugeValue, error,
|
||||
prometheus.GaugeValue, errorMetric,
|
||||
)
|
||||
return nil
|
||||
}
|
||||
|
||||
func scrapeFile(path string, log log.Logger) ([]*dto.MetricFamily, error) {
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var parser expfmt.TextParser
|
||||
r, encoding := utfbom.Skip(carriageReturnFilteringReader{r: file})
|
||||
if err = checkBOM(encoding); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
parsedFamilies, err := parser.TextToMetricFamilies(r)
|
||||
closeErr := file.Close()
|
||||
if closeErr != nil {
|
||||
_ = level.Warn(log).Log("msg", fmt.Sprintf("Error closing file %q", path), "err", closeErr)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Use temporary array to check for duplicates
|
||||
var families_array []*dto.MetricFamily
|
||||
|
||||
for _, mf := range parsedFamilies {
|
||||
families_array = append(families_array, mf)
|
||||
for _, m := range mf.Metric {
|
||||
if m.TimestampMs != nil {
|
||||
return nil, fmt.Errorf("textfile contains unsupported client-side timestamps")
|
||||
}
|
||||
}
|
||||
if mf.Help == nil {
|
||||
help := fmt.Sprintf("Metric read from %s", path)
|
||||
mf.Help = &help
|
||||
}
|
||||
}
|
||||
|
||||
// If duplicate metrics are detected in a *single* file, skip processing of file metrics
|
||||
if duplicateMetricEntry(families_array) {
|
||||
return nil, fmt.Errorf("duplicate metrics detected")
|
||||
}
|
||||
return families_array, nil
|
||||
}
|
||||
|
||||
func checkBOM(encoding utfbom.Encoding) error {
|
||||
if encoding == utfbom.Unknown || encoding == utfbom.UTF8 {
|
||||
return nil
|
||||
|
||||
@@ -1,19 +1,25 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/dimchansky/utfbom"
|
||||
"github.com/go-kit/log"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
dto "github.com/prometheus/client_model/go"
|
||||
)
|
||||
|
||||
var baseDir = "../tools/textfile-test"
|
||||
|
||||
func TestCRFilter(t *testing.T) {
|
||||
sr := strings.NewReader("line 1\r\nline 2")
|
||||
cr := carriageReturnFilteringReader{r: sr}
|
||||
b, err := ioutil.ReadAll(cr)
|
||||
b, err := io.ReadAll(cr)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
@@ -153,3 +159,73 @@ func TestDuplicateMetricEntry(t *testing.T) {
|
||||
t.Errorf("Unexpected duplicate found in differentValues")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMultipleDirectories(t *testing.T) {
|
||||
testDir := baseDir + "/multiple-dirs"
|
||||
testDirs := fmt.Sprintf("%[1]s/dir1,%[1]s/dir2,%[1]s/dir3", testDir)
|
||||
collector := &textFileCollector{
|
||||
logger: log.NewLogfmtLogger(os.Stdout),
|
||||
directories: testDirs,
|
||||
}
|
||||
scrapeContext, err := PrepareScrapeContext([]string{"textfile_test"})
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error %s", err)
|
||||
}
|
||||
metrics := make(chan prometheus.Metric)
|
||||
got := ""
|
||||
go func() {
|
||||
for {
|
||||
var metric dto.Metric
|
||||
val := <-metrics
|
||||
err := val.Write(&metric)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error %s", err)
|
||||
}
|
||||
got += metric.String()
|
||||
}
|
||||
}()
|
||||
err = collector.Collect(scrapeContext, metrics)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error %s", err)
|
||||
}
|
||||
for _, f := range []string{"dir1", "dir2", "dir3", "dir3sub"} {
|
||||
if !strings.Contains(got, f) {
|
||||
t.Errorf("Unexpected output %s: %q", f, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDuplicateFileName(t *testing.T) {
|
||||
testDir := baseDir + "/duplicate-filename"
|
||||
collector := &textFileCollector{
|
||||
logger: log.NewLogfmtLogger(os.Stdout),
|
||||
directories: testDir,
|
||||
}
|
||||
scrapeContext, err := PrepareScrapeContext([]string{"textfile_test"})
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error %s", err)
|
||||
}
|
||||
metrics := make(chan prometheus.Metric)
|
||||
got := ""
|
||||
go func() {
|
||||
for {
|
||||
var metric dto.Metric
|
||||
val := <-metrics
|
||||
err := val.Write(&metric)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error %s", err)
|
||||
}
|
||||
got += metric.String()
|
||||
}
|
||||
}()
|
||||
err = collector.Collect(scrapeContext, metrics)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error %s", err)
|
||||
}
|
||||
if !strings.Contains(got, "file") {
|
||||
t.Errorf("Unexpected output %q", got)
|
||||
}
|
||||
if strings.Contains(got, "sub_file") {
|
||||
t.Errorf("Unexpected output %q", got)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,8 +18,8 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/go-kit/log"
|
||||
@@ -40,11 +40,8 @@ type Resolver struct {
|
||||
func NewResolver(file string, logger log.Logger, insecure_skip_verify bool) (*Resolver, error) {
|
||||
flags := map[string]string{}
|
||||
var fileBytes []byte
|
||||
url, err := url.ParseRequestURI(file)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if url.Scheme == "http" || url.Scheme == "https" {
|
||||
var err error
|
||||
if strings.HasPrefix(file, "http://") || strings.HasPrefix(file, "https://") {
|
||||
_ = level.Info(logger).Log("msg", fmt.Sprintf("Loading configuration file from URL: %v", file))
|
||||
tr := &http.Transport{
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: insecure_skip_verify},
|
||||
|
||||
@@ -59,6 +59,7 @@ Name | Description | Type | Labels
|
||||
`windows_ad_ldap_searches_total` | _Not yet documented_ | counter | None
|
||||
`windows_ad_ldap_udp_operations_total` | _Not yet documented_ | counter | None
|
||||
`windows_ad_ldap_writes_total` | _Not yet documented_ | counter | None
|
||||
`windows_ad_ldap_client_sessions` | This is the number of sessions opened by LDAP clients at the time the data is taken. This is helpful in determining LDAP client activity and if the DC is able to handle the load. Of course, spikes during normal periods of authentication — such as first thing in the morning — are not necessarily a problem, but long sustained periods of high values indicate an overworked DC | gauge | None
|
||||
`windows_ad_link_values_cleaned_total` | _Not yet documented_ | counter | None
|
||||
`windows_ad_phantom_objects_cleaned_total` | _Not yet documented_ | counter | None
|
||||
`windows_ad_phantom_objects_visited_total` | _Not yet documented_ | counter | None
|
||||
|
||||
@@ -28,49 +28,39 @@ Name | Description | Type | Labels
|
||||
`windows_adfs_password_change_succeeded_total` | Total number of succeeded password changes. The Password Change Portal must be enabled in the AD FS Management tool in order to allow user password changes | counter | None
|
||||
`windows_adfs_token_requests_total` | Total number of requested access tokens | counter | None
|
||||
`windows_adfs_windows_integrated_authentications_total` | Total number of Windows integrated authentications using Kerberos or NTLM | counter | None
|
||||
`ad_login_connection_failures_total` | Total number of connection failures to an Active Directory domain controller | counter | None
|
||||
`certificate_authentications_total` | Total number of User Certificate authentications | counter | None
|
||||
`device_authentications_total` | Total number of Device authentications | counter | None
|
||||
`extranet_account_lockouts_total` | Total number of Extranet Account Lockouts | counter | None
|
||||
`federated_authentications_total` | Total number of authentications from a federated source | counter | None
|
||||
`passport_authentications_total` | Total number of Microsoft Passport SSO authentications | counter | None
|
||||
`passive_requests_total` | Total number of passive (browser-based) requests | counter | None
|
||||
`password_change_failed_total` | Total number of failed password changes | counter | None
|
||||
`password_change_succeeded_total` | Total number of successful password changes | counter | None
|
||||
`token_requests_total` | Total number of token requests | counter | None
|
||||
`windows_integrated_authentications_total` | Total number of Windows integrated authentications (Kerberos/NTLM) | counter | None
|
||||
`oauth_authorization_requests_total` | Total number of incoming requests to the OAuth Authorization endpoint | counter | None
|
||||
`oauth_client_authentication_success_total` | Total number of successful OAuth client Authentications | counter | None
|
||||
`oauth_client_authentication_failure_total` | Total number of failed OAuth client Authentications | counter | None
|
||||
`oauth_client_credentials_failure_total` | Total number of failed OAuth Client Credentials Requests | counter | None
|
||||
`oauth_client_credentials_success_total` | Total number of successful RP tokens issued for OAuth Client Credentials Requests | counter | None
|
||||
`oauth_client_privkey_jwt_authentication_failure_total` | Total number of failed OAuth Client Private Key Jwt Authentications | counter | None
|
||||
`oauth_client_privkey_jwt_authentications_success_total` | Total number of successful OAuth Client Private Key Jwt Authentications | counter | None
|
||||
`oauth_client_secret_basic_authentications_failure_total` | Total number of failed OAuth Client Secret Basic Authentications | counter | None
|
||||
`oauth_client_secret_basic_authentications_success_total` | Total number of successful OAuth Client Secret Basic Authentications | counter | None
|
||||
`oauth_client_secret_post_authentications_failure_total` | Total number of failed OAuth Client Secret Post Authentications | counter | None
|
||||
`oauth_client_secret_post_authentications_success_total` | Total number of successful OAuth Client Secret Post Authentications | counter | None
|
||||
`oauth_client_windows_authentications_failure_total` | Total number of failed OAuth Client Windows Integrated Authentications | counter | None
|
||||
`oauth_client_windows_authentications_success_total` | Total number of successful OAuth Client Windows Integrated Authentications | counter | None
|
||||
`oauth_logon_certificate_requests_failure_total` | Total number of failed OAuth Logon Certificate Requests | counter | None
|
||||
`oauth_logon_certificate_token_requests_success_total` | Total number of successful RP tokens issued for OAuth Logon Certificate Requests | counter | None
|
||||
`oauth_password_grant_requests_failure_total` | Total number of failed OAuth Password Grant Requests | counter | None
|
||||
`oauth_password_grant_requests_success_total` | Total number of successful OAuth Password Grant Requests | counter | None
|
||||
`oauth_token_requests_success_total` | Total number of successful RP tokens issued over OAuth protocol | counter | None
|
||||
`samlp_token_requests_success_total` | Total number of successful RP tokens issued over SAML-P protocol | counter | None
|
||||
`sso_authentications_failure_total` | Total number of failed SSO authentications | counter | None
|
||||
`sso_authentications_success_total` | Total number of successful SSO authentications | counter | None
|
||||
`wsfed_token_requests_success_total` | Total number of successful RP tokens issued over WS-Fed protocol | counter | None
|
||||
`wstrust_token_requests_success_total` | Total number of successful RP tokens issued over WS-Trust protocol | counter | None
|
||||
`userpassword_authentications_failure_total` | Total number of failed AD U/P authentications | counter | None
|
||||
`userpassword_authentications_success_total` | Total number of successful AD U/P authentications | counter | None
|
||||
`external_authentications_failure_total` | Total number of failed authentications from external MFA providers | counter | None
|
||||
`external_authentications_success_total` | Total number of successful authentications from external MFA providers | counter | None
|
||||
`db_artifact_failure_total` | Total number of failures connecting to the artifact database | counter | None
|
||||
`db_artifact_query_time_seconds_total` | Accumulator of time taken for an artifact database query | counter | None
|
||||
`db_config_failure_total` | Total number of failures connecting to the configuration database | counter | None
|
||||
`db_config_query_time_seconds_total` | Accumulator of time taken for a configuration database query | counter | None
|
||||
`federation_metadata_requests_total` | Total number of Federation Metadata requests | counter | None
|
||||
`windows_adfs_passive_requests_total` | Total number of passive (browser-based) requests | counter | None
|
||||
`windows_adfs_oauth_authorization_requests_total` | Total number of incoming requests to the OAuth Authorization endpoint | counter | None
|
||||
`windows_adfs_oauth_client_authentication_success_total` | Total number of successful OAuth client Authentications | counter | None
|
||||
`windows_adfs_oauth_client_authentication_failure_total` | Total number of failed OAuth client Authentications | counter | None
|
||||
`windows_adfs_oauth_client_credentials_failure_total` | Total number of failed OAuth Client Credentials Requests | counter | None
|
||||
`windows_adfs_oauth_client_credentials_success_total` | Total number of successful RP tokens issued for OAuth Client Credentials Requests | counter | None
|
||||
`windows_adfs_oauth_client_privkey_jwt_authentication_failure_total` | Total number of failed OAuth Client Private Key Jwt Authentications | counter | None
|
||||
`windows_adfs_oauth_client_privkey_jwt_authentications_success_total` | Total number of successful OAuth Client Private Key Jwt Authentications | counter | None
|
||||
`windows_adfs_oauth_client_secret_basic_authentications_failure_total` | Total number of failed OAuth Client Secret Basic Authentications | counter | None
|
||||
`windows_adfs_oauth_client_secret_basic_authentications_success_total` | Total number of successful OAuth Client Secret Basic Authentications | counter | None
|
||||
`windows_adfs_oauth_client_secret_post_authentications_failure_total` | Total number of failed OAuth Client Secret Post Authentications | counter | None
|
||||
`windows_adfs_oauth_client_secret_post_authentications_success_total` | Total number of successful OAuth Client Secret Post Authentications | counter | None
|
||||
`windows_adfs_oauth_client_windows_authentications_failure_total` | Total number of failed OAuth Client Windows Integrated Authentications | counter | None
|
||||
`windows_adfs_oauth_client_windows_authentications_success_total` | Total number of successful OAuth Client Windows Integrated Authentications | counter | None
|
||||
`windows_adfs_oauth_logon_certificate_requests_failure_total` | Total number of failed OAuth Logon Certificate Requests | counter | None
|
||||
`windows_adfs_oauth_logon_certificate_token_requests_success_total` | Total number of successful RP tokens issued for OAuth Logon Certificate Requests | counter | None
|
||||
`windows_adfs_oauth_password_grant_requests_failure_total` | Total number of failed OAuth Password Grant Requests | counter | None
|
||||
`windows_adfs_oauth_password_grant_requests_success_total` | Total number of successful OAuth Password Grant Requests | counter | None
|
||||
`windows_adfs_oauth_token_requests_success_total` | Total number of successful RP tokens issued over OAuth protocol | counter | None
|
||||
`windows_adfs_samlp_token_requests_success_total` | Total number of successful RP tokens issued over SAML-P protocol | counter | None
|
||||
`windows_adfs_sso_authentications_failure_total` | Total number of failed SSO authentications | counter | None
|
||||
`windows_adfs_sso_authentications_success_total` | Total number of successful SSO authentications | counter | None
|
||||
`windows_adfs_wsfed_token_requests_success_total` | Total number of successful RP tokens issued over WS-Fed protocol | counter | None
|
||||
`windows_adfs_wstrust_token_requests_success_total` | Total number of successful RP tokens issued over WS-Trust protocol | counter | None
|
||||
`windows_adfs_userpassword_authentications_failure_total` | Total number of failed AD U/P authentications | counter | None
|
||||
`windows_adfs_userpassword_authentications_success_total` | Total number of successful AD U/P authentications | counter | None
|
||||
`windows_adfs_external_authentications_failure_total` | Total number of failed authentications from external MFA providers | counter | None
|
||||
`windows_adfs_external_authentications_success_total` | Total number of successful authentications from external MFA providers | counter | None
|
||||
`windows_adfs_db_artifact_failure_total` | Total number of failures connecting to the artifact database | counter | None
|
||||
`windows_adfs_db_artifact_query_time_seconds_total` | Accumulator of time taken for an artifact database query | counter | None
|
||||
`windows_adfs_db_config_failure_total` | Total number of failures connecting to the configuration database | counter | None
|
||||
`windows_adfs_db_config_query_time_seconds_total` | Accumulator of time taken for a configuration database query | counter | None
|
||||
`windows_adfs_federation_metadata_requests_total` | Total number of Federation Metadata requests | counter | None
|
||||
|
||||
### Example metric
|
||||
Show rate of device authentications in AD FS:
|
||||
|
||||
@@ -51,9 +51,11 @@ Name | Description | Type | Labels
|
||||
`windows_hyperv_host_cpu_hypervisor_run_time` | _Not yet documented_ | counter | `core`
|
||||
`windows_hyperv_host_cpu_remote_run_time` | _Not yet documented_ | counter | `core`
|
||||
`windows_hyperv_host_cpu_total_run_time` | _Not yet documented_ | counter | `core`
|
||||
`windows_hyperv_host_cpu_wait_time_per_dispatch_total` | _Not yet documented_ | counter | `core`
|
||||
`windows_hyperv_vm_cpu_guest_run_time` | _Not yet documented_ | counter | `vm`, `core`
|
||||
`windows_hyperv_vm_cpu_hypervisor_run_time` | _Not yet documented_ | counter | `vm`, `core`
|
||||
`windows_hyperv_vm_cpu_remote_run_time` | _Not yet documented_ | counter | `vm`, `core`
|
||||
`windows_hyperv_vm_cpu_wait_time_per_dispatch_total` | _Not yet documented_ | counter | `vm`, `core`
|
||||
`windows_hyperv_vm_memory_added_total` | _Not yet documented_ | counter | `vm`
|
||||
`windows_hyperv_vm_memory_pressure_average` | _Not yet documented_ | gauge | `vm`
|
||||
`windows_hyperv_vm_memory_pressure_current` | _Not yet documented_ | counter | `vm`
|
||||
|
||||
80
docs/collector.physical_disk.md
Normal file
80
docs/collector.physical_disk.md
Normal file
@@ -0,0 +1,80 @@
|
||||
# physical_disk collector
|
||||
|
||||
The physical_disk collector exposes metrics about physical disks
|
||||
|
||||
|||
|
||||
-|-
|
||||
Metric name prefix | `physical_disk`
|
||||
Data source | Perflib
|
||||
Counters | `physicalDisk` ([`Win32_PerfRawData_PerfDisk_physicalDisk`](https://msdn.microsoft.com/en-us/windows/hardware/aa394307(v=vs.71)))
|
||||
Enabled by default? | Yes
|
||||
|
||||
## Flags
|
||||
|
||||
### `--collector.physical_disk.disk-include`
|
||||
|
||||
If given, a disk needs to match the include regexp in order for the corresponding disk metrics to be reported
|
||||
|
||||
### `--collector.physical_disk.disk-exclude`
|
||||
|
||||
If given, a disk needs to *not* match the exclude regexp in order for the corresponding disk metrics to be reported
|
||||
|
||||
## Metrics
|
||||
|
||||
Name | Description | Type | Labels
|
||||
-----|-------------|------|-------
|
||||
`requests_queued` | Number of requests outstanding on the disk at the time the performance data is collected | gauge | `disk`
|
||||
`read_bytes_total` | Rate at which bytes are transferred from the disk during read operations | counter | `disk`
|
||||
`reads_total` | Rate of read operations on the disk | counter | `disk`
|
||||
`write_bytes_total` | Rate at which bytes are transferred to the disk during write operations | counter | `disk`
|
||||
`writes_total` | Rate of write operations on the disk | counter | `disk`
|
||||
`read_seconds_total` | Seconds the disk was busy servicing read requests | counter | `disk`
|
||||
`write_seconds_total` | Seconds the disk was busy servicing write requests | counter | `disk`
|
||||
`free_bytes` | Unused space of the disk in bytes (not real time, updates every 10-15 min) | gauge | `disk`
|
||||
`size_bytes` | Total size of the disk in bytes (not real time, updates every 10-15 min) | gauge | `disk`
|
||||
`idle_seconds_total` | Seconds the disk was idle (not servicing read/write requests) | counter | `disk`
|
||||
`split_ios_total` | Number of I/Os to the disk split into multiple I/Os | counter | `disk`
|
||||
|
||||
### Warning about size metrics
|
||||
The `free_bytes` and `size_bytes` metrics are not updated in real time and might have a delay of 10-15min.
|
||||
This is the same behavior as the windows performance counters.
|
||||
|
||||
### Example metric
|
||||
Query the rate of write operations to a disk
|
||||
```
|
||||
rate(windows_physical_disk_read_bytes_total{instance="localhost", disk=~"0"}[2m])
|
||||
```
|
||||
|
||||
## Useful queries
|
||||
Calculate rate of total IOPS for disk
|
||||
```
|
||||
rate(windows_physical_disk_reads_total{instance="localhost", disk=~"0"}[2m]) + rate(windows_physical_disk_writes_total{instance="localhost", disk=~"0"}[2m])
|
||||
```
|
||||
|
||||
## Alerting examples
|
||||
**prometheus.rules**
|
||||
```yaml
|
||||
groups:
|
||||
- name: Windows Disk Alerts
|
||||
rules:
|
||||
|
||||
# Sends an alert when disk space usage is above 95%
|
||||
- alert: DiskSpaceUsage
|
||||
expr: 100.0 - 100 * (windows_physical_disk_free_bytes / windows_physical_disk_size_bytes) > 95
|
||||
for: 10m
|
||||
labels:
|
||||
severity: high
|
||||
annotations:
|
||||
summary: "Disk Space Usage (instance {{ $labels.instance }})"
|
||||
description: "Disk Space on Drive is used more than 95%\n VALUE = {{ $value }}\n LABELS: {{ $labels }}"
|
||||
|
||||
# Alerts on disks with over 85% space usage predicted to fill within the next four days
|
||||
- alert: DiskFilling
|
||||
expr: 100 * (windows_physical_disk_free_bytes / windows_physical_disk_size_bytes) < 15 and predict_linear(windows_physical_disk_free_bytes[6h], 4 * 24 * 3600) < 0
|
||||
for: 10m
|
||||
labels:
|
||||
severity: warning
|
||||
annotations:
|
||||
summary: "Disk full in four days (instance {{ $labels.instance }})"
|
||||
description: "{{ $labels.disk }} is expected to fill up within four days. Currently {{ $value | humanize }}% is available.\n VALUE = {{ $value }}\n LABELS: {{ $labels }}"
|
||||
```
|
||||
@@ -21,7 +21,7 @@ Name | Description | Type | Labels
|
||||
`windows_tcp_connections_active_total` | Number of times TCP connections have made a direct transition from the CLOSED state to the SYN-SENT state.| counter | af
|
||||
`windows_tcp_connections_established` | Number of TCP connections for which the current state is either ESTABLISHED or CLOSE-WAIT. | gauge | af
|
||||
`windows_tcp_connections_passive_total` | Number of times TCP connections have made a direct transition from the LISTEN state to the SYN-RCVD state. | counter | af
|
||||
`windows_tcp_connections_reset_total` | Number of times TCP connections have made a direct transition from the LISTEN state to the SYN-RCVD state. | counter | af
|
||||
`windows_tcp_connections_reset_total` | Connections Reset is the number of times TCP connections have made a direct transition to the CLOSED state from either the ESTABLISHED state or the CLOSE-WAIT state. | counter | af
|
||||
`windows_tcp_segments_total` | Total segments sent or received using the TCP protocol | counter | af
|
||||
`windows_tcp_segments_received_total` | Total segments received, including those received in error. This count includes segments received on currently established connections | counter | af
|
||||
`windows_tcp_segments_retransmitted_total` | Total segments retransmitted. That is, segments transmitted that contain one or more previously transmitted bytes | counter | af
|
||||
|
||||
@@ -10,15 +10,25 @@ Enabled by default? | Yes
|
||||
|
||||
## Flags
|
||||
|
||||
### `--collector.textfile.directory`
|
||||
### `--collector.textfile.directory`
|
||||
:warning: DEPRECATED Use `--collector.textfile.directories`
|
||||
|
||||
The directory containing the files to be ingested. Only files with the extension `.prom` are read. The `.prom` file must end with an empty line feed to work properly.
|
||||
<br>
|
||||
|
||||
### `--collector.textfile.directories`
|
||||
One or multiple directories containing the files to be ingested.
|
||||
|
||||
E.G. `--collector.textfile.directories="C:\MyDir1,C:\MyDir2"`
|
||||
|
||||
Default value: `C:\Program Files\windows_exporter\textfile_inputs`
|
||||
|
||||
Required: No
|
||||
|
||||
## Metrics
|
||||
> **Note:**
|
||||
> - If there are duplicated filenames among the directories, only the first one found will be read. For any other files with the same name, the `windows_textfile_scrape_error` metric will be set to 1 and a error message will be logged.
|
||||
> - Only files with the extension `.prom` are read. The `.prom` file must end with an empty line feed to work properly.
|
||||
|
||||
|
||||
|
||||
Metrics will primarily come from the files on disk. The below listed metrics
|
||||
are collected to give information about the reading of the metrics themselves.
|
||||
@@ -38,7 +48,7 @@ _This collector does not yet have any useful queries added, we would appreciate
|
||||
_This collector does not yet have alerting examples, we would appreciate your help adding them!_
|
||||
|
||||
# Example use
|
||||
This Powershell script, when run in the `collector.textfile.directory` (default `C:\Program Files\windows_exporter\textfile_inputs`), generates a valid `.prom` file that should successfully ingested by windows_exporter.
|
||||
This Powershell script, when run in the `--collector.textfile.directories` (default `C:\Program Files\windows_exporter\textfile_inputs`), generates a valid `.prom` file that should successfully ingested by windows_exporter.
|
||||
|
||||
```Powershell
|
||||
$alpha = 42
|
||||
|
||||
@@ -49,7 +49,7 @@ type prometheusVersion struct {
|
||||
}
|
||||
|
||||
const (
|
||||
defaultCollectors = "cpu,cs,logical_disk,net,os,service,system,textfile"
|
||||
defaultCollectors = "cpu,cs,logical_disk,physical_disk,net,os,service,system,textfile"
|
||||
defaultCollectorsPlaceholder = "[defaults]"
|
||||
)
|
||||
|
||||
|
||||
26
go.mod
26
go.mod
@@ -3,45 +3,51 @@ module github.com/prometheus-community/windows_exporter
|
||||
go 1.19
|
||||
|
||||
require (
|
||||
github.com/Microsoft/hcsshim v0.9.8
|
||||
github.com/Microsoft/hcsshim v0.11.1
|
||||
github.com/alecthomas/kingpin/v2 v2.3.2
|
||||
github.com/dimchansky/utfbom v1.1.1
|
||||
github.com/go-kit/log v0.2.1
|
||||
github.com/go-ole/go-ole v1.2.6
|
||||
github.com/go-ole/go-ole v1.3.0
|
||||
github.com/prometheus/client_golang v1.16.0
|
||||
github.com/prometheus/client_model v0.4.0
|
||||
github.com/prometheus/common v0.44.0
|
||||
github.com/prometheus/exporter-toolkit v0.10.0
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.3
|
||||
go.opencensus.io v0.23.0 // indirect
|
||||
golang.org/x/sys v0.10.0
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
golang.org/x/sys v0.12.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/Microsoft/go-winio v0.4.17 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.1 // indirect
|
||||
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/containerd/cgroups v1.0.1 // indirect
|
||||
github.com/containerd/cgroups v1.1.0 // indirect
|
||||
github.com/containerd/containerd v1.7.0 // indirect
|
||||
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
|
||||
github.com/go-logfmt/logfmt v0.5.1 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/jpillora/backoff v1.0.0 // indirect
|
||||
github.com/kr/text v0.2.0 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/prometheus/procfs v0.10.1 // indirect
|
||||
github.com/xhit/go-str2duration/v2 v2.1.0 // indirect
|
||||
golang.org/x/crypto v0.8.0 // indirect
|
||||
golang.org/x/crypto v0.9.0 // indirect
|
||||
golang.org/x/mod v0.10.0 // indirect
|
||||
golang.org/x/net v0.10.0 // indirect
|
||||
golang.org/x/oauth2 v0.8.0 // indirect
|
||||
golang.org/x/sync v0.2.0 // indirect
|
||||
golang.org/x/sync v0.3.0 // indirect
|
||||
golang.org/x/text v0.9.0 // indirect
|
||||
golang.org/x/tools v0.8.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/protobuf v1.30.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect
|
||||
google.golang.org/grpc v1.56.2 // indirect
|
||||
google.golang.org/protobuf v1.31.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
)
|
||||
|
||||
@@ -32,14 +32,14 @@ loop:
|
||||
changes <- c.CurrentStatus
|
||||
case svc.Stop, svc.Shutdown:
|
||||
_ = logger.Info(100, "Service Stop Received")
|
||||
s.stopCh <- true
|
||||
changes <- svc.Status{State: svc.StopPending}
|
||||
break loop
|
||||
default:
|
||||
_ = logger.Error(102, fmt.Sprintf("unexpected control request #%d", c))
|
||||
}
|
||||
}
|
||||
}
|
||||
changes <- svc.Status{State: svc.StopPending}
|
||||
s.stopCh <- true
|
||||
return
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ var StopCh = make(chan bool)
|
||||
func init() {
|
||||
isService, err := svc.IsWindowsService()
|
||||
if err != nil {
|
||||
logger, err := eventlog.Open("windows_exporter")
|
||||
logger, err = eventlog.Open("windows_exporter")
|
||||
if err != nil {
|
||||
os.Exit(2)
|
||||
}
|
||||
@@ -57,7 +57,7 @@ func init() {
|
||||
}
|
||||
|
||||
if isService {
|
||||
logger, err := eventlog.Open("windows_exporter")
|
||||
logger, err = eventlog.Open("windows_exporter")
|
||||
if err != nil {
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
<fw:RemoteAddress>[REMOTE_ADDR]</fw:RemoteAddress>
|
||||
</fw:FirewallException>
|
||||
</File>
|
||||
<ServiceInstall Id="InstallExporterService" Name="windows_exporter" DisplayName="windows_exporter" Description="Exports Prometheus metrics about the system" ErrorControl="normal" Start="auto" Type="ownProcess" Arguments="--log.format eventlog [CollectorsFlag] [ListenFlagBoth] [ListenFlagAddr] [ListenFlagPort] [MetricsPathFlag] [TextfileDirFlag] [ExtraFlags]">
|
||||
<ServiceInstall Id="InstallExporterService" Name="windows_exporter" DisplayName="windows_exporter" Description="Exports Prometheus metrics about the system" ErrorControl="normal" Start="auto" Type="ownProcess" Arguments="--log.file eventlog [CollectorsFlag] [ListenFlagBoth] [ListenFlagAddr] [ListenFlagPort] [MetricsPathFlag] [TextfileDirFlag] [ExtraFlags]">
|
||||
<util:ServiceConfig FirstFailureActionType="restart" SecondFailureActionType="restart" ThirdFailureActionType="restart" RestartServiceDelayInSeconds="60" />
|
||||
<ServiceDependency Id="wmiApSrv" />
|
||||
</ServiceInstall>
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: monitoring
|
||||
labels:
|
||||
name: monitoring
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: DaemonSet
|
||||
metadata:
|
||||
|
||||
@@ -24,6 +24,7 @@ func (f *AllowedFile) String() string {
|
||||
|
||||
// Set updates the value of the allowed format.
|
||||
func (f *AllowedFile) Set(s string) error {
|
||||
f.s = s
|
||||
switch s {
|
||||
case "stdout":
|
||||
f.w = os.Stdout
|
||||
@@ -77,6 +78,8 @@ func New(config *Config) (log.Logger, error) {
|
||||
return nil, err
|
||||
}
|
||||
l = eventlog.NewEventLogLogger(w, loggerFunc)
|
||||
} else if config.File.w == nil {
|
||||
panic("logger: file writer is nil")
|
||||
} else {
|
||||
l = loggerFunc(log.NewSyncWriter(config.File.w))
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@ test_alpha_total 42
|
||||
windows_exporter_collector_success{collector="cpu"} 1
|
||||
windows_exporter_collector_success{collector="cs"} 1
|
||||
windows_exporter_collector_success{collector="logical_disk"} 1
|
||||
windows_exporter_collector_success{collector="physical_disk"} 1
|
||||
windows_exporter_collector_success{collector="net"} 1
|
||||
windows_exporter_collector_success{collector="os"} 1
|
||||
windows_exporter_collector_success{collector="service"} 1
|
||||
@@ -50,6 +51,7 @@ windows_exporter_collector_success{collector="textfile"} 1
|
||||
windows_exporter_collector_timeout{collector="cpu"} 0
|
||||
windows_exporter_collector_timeout{collector="cs"} 0
|
||||
windows_exporter_collector_timeout{collector="logical_disk"} 0
|
||||
windows_exporter_collector_timeout{collector="physical_disk"} 0
|
||||
windows_exporter_collector_timeout{collector="net"} 0
|
||||
windows_exporter_collector_timeout{collector="os"} 0
|
||||
windows_exporter_collector_timeout{collector="service"} 0
|
||||
@@ -89,6 +91,30 @@ windows_exporter_collector_timeout{collector="textfile"} 0
|
||||
# TYPE windows_logical_disk_write_seconds_total counter
|
||||
# HELP windows_logical_disk_writes_total The number of write operations on the disk (LogicalDisk.DiskWritesPerSec)
|
||||
# TYPE windows_logical_disk_writes_total counter
|
||||
# HELP windows_physical_disk_idle_seconds_total Seconds that the disk was idle (PhysicalDisk.PercentIdleTime)
|
||||
# TYPE windows_physical_disk_idle_seconds_total counter
|
||||
# HELP windows_physical_disk_read_bytes_total The number of bytes transferred from the disk during read operations (PhysicalDisk.DiskReadBytesPerSec)
|
||||
# TYPE windows_physical_disk_read_bytes_total counter
|
||||
# HELP windows_physical_disk_read_latency_seconds_total Shows the average time, in seconds, of a read operation from the disk (PhysicalDisk.AvgDiskSecPerRead)
|
||||
# TYPE windows_physical_disk_read_latency_seconds_total counter
|
||||
# HELP windows_physical_disk_read_seconds_total Seconds that the disk was busy servicing read requests (PhysicalDisk.PercentDiskReadTime)
|
||||
# TYPE windows_physical_disk_read_seconds_total counter
|
||||
# HELP windows_physical_disk_read_write_latency_seconds_total Shows the time, in seconds, of the average disk transfer (PhysicalDisk.AvgDiskSecPerTransfer)
|
||||
# TYPE windows_physical_disk_read_write_latency_seconds_total counter
|
||||
# HELP windows_physical_disk_reads_total The number of read operations on the disk (PhysicalDisk.DiskReadsPerSec)
|
||||
# TYPE windows_physical_disk_reads_total counter
|
||||
# HELP windows_physical_disk_requests_queued The number of requests queued to the disk (PhysicalDisk.CurrentDiskQueueLength)
|
||||
# TYPE windows_physical_disk_requests_queued gauge
|
||||
# HELP windows_physical_disk_split_ios_total The number of I/Os to the disk were split into multiple I/Os (PhysicalDisk.SplitIOPerSec)
|
||||
# TYPE windows_physical_disk_split_ios_total counter
|
||||
# HELP windows_physical_disk_write_bytes_total The number of bytes transferred to the disk during write operations (PhysicalDisk.DiskWriteBytesPerSec)
|
||||
# TYPE windows_physical_disk_write_bytes_total counter
|
||||
# HELP windows_physical_disk_write_latency_seconds_total Shows the average time, in seconds, of a write operation to the disk (PhysicalDisk.AvgDiskSecPerWrite)
|
||||
# TYPE windows_physical_disk_write_latency_seconds_total counter
|
||||
# HELP windows_physical_disk_write_seconds_total Seconds that the disk was busy servicing write requests (PhysicalDisk.PercentDiskWriteTime)
|
||||
# TYPE windows_physical_disk_write_seconds_total counter
|
||||
# HELP windows_physical_disk_writes_total The number of write operations on the disk (PhysicalDisk.DiskWritesPerSec)
|
||||
# TYPE windows_physical_disk_writes_total counter
|
||||
# HELP windows_net_bytes_received_total (Network.BytesReceivedPerSec)
|
||||
# TYPE windows_net_bytes_received_total counter
|
||||
# HELP windows_net_bytes_sent_total (Network.BytesSentPerSec)
|
||||
|
||||
@@ -18,7 +18,7 @@ mkdir $textfile_dir | Out-Null
|
||||
Copy-Item 'e2e-textfile.prom' -Destination "$($textfile_dir)/e2e-textfile.prom"
|
||||
|
||||
# Omit dynamic collector information that will change after each run
|
||||
$skip_re = "^(go_|windows_exporter_build_info|windows_exporter_collector_duration_seconds|windows_exporter_perflib_snapshot_duration_seconds|process_|windows_textfile_mtime_seconds|windows_cpu|windows_cs|windows_logical_disk|windows_net|windows_os|windows_service|windows_system|windows_textfile_mtime_seconds)"
|
||||
$skip_re = "^(go_|windows_exporter_build_info|windows_exporter_collector_duration_seconds|windows_exporter_perflib_snapshot_duration_seconds|process_|windows_textfile_mtime_seconds|windows_cpu|windows_cs|windows_logical_disk|windows_physical_disk|windows_net|windows_os|windows_service|windows_system|windows_textfile_mtime_seconds)"
|
||||
|
||||
# Start process in background, awaiting HTTP requests.
|
||||
# Use default collectors, port and address: http://localhost:9182/metrics
|
||||
|
||||
3
tools/textfile-test/duplicate-filename/file.prom
Normal file
3
tools/textfile-test/duplicate-filename/file.prom
Normal file
@@ -0,0 +1,3 @@
|
||||
# HELP windows_test Some Test
|
||||
# TYPE windows_test gauge
|
||||
windows_test{flag="file"} 1
|
||||
3
tools/textfile-test/duplicate-filename/sub/file.prom
Normal file
3
tools/textfile-test/duplicate-filename/sub/file.prom
Normal file
@@ -0,0 +1,3 @@
|
||||
# HELP windows_test Some Test
|
||||
# TYPE windows_test gauge
|
||||
windows_test{flag="sub_file"} 2
|
||||
3
tools/textfile-test/multiple-dirs/dir1/dir1.prom
Normal file
3
tools/textfile-test/multiple-dirs/dir1/dir1.prom
Normal file
@@ -0,0 +1,3 @@
|
||||
# HELP windows_test Some Test
|
||||
# TYPE windows_test gauge
|
||||
windows_test{flag="dir1"} 1
|
||||
3
tools/textfile-test/multiple-dirs/dir2/dir2.prom
Normal file
3
tools/textfile-test/multiple-dirs/dir2/dir2.prom
Normal file
@@ -0,0 +1,3 @@
|
||||
# HELP windows_test Some Test
|
||||
# TYPE windows_test gauge
|
||||
windows_test{flag="dir2"} 2
|
||||
3
tools/textfile-test/multiple-dirs/dir3/dir3.prom
Normal file
3
tools/textfile-test/multiple-dirs/dir3/dir3.prom
Normal file
@@ -0,0 +1,3 @@
|
||||
# HELP windows_test Some Test
|
||||
# TYPE windows_test gauge
|
||||
windows_test{flag="dir3"} 3
|
||||
@@ -0,0 +1,3 @@
|
||||
# HELP windows_test Some Test
|
||||
# TYPE windows_test gauge
|
||||
windows_test{flag="dir3sub"} 3
|
||||
Reference in New Issue
Block a user