mirror of
https://github.com/prometheus-community/windows_exporter.git
synced 2026-03-04 09:36:35 +00:00
msmq: Use Performance Counter instead WMI (#1766)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
This commit is contained in:
@@ -2,26 +2,22 @@
|
|||||||
|
|
||||||
The msmq collector exposes metrics about the queues on a MSMQ server
|
The msmq collector exposes metrics about the queues on a MSMQ server
|
||||||
|
|
||||||
|||
|
| | |
|
||||||
-|-
|
|---------------------|----------------------|
|
||||||
Metric name prefix | `msmq`
|
| Metric name prefix | `msmq` |
|
||||||
Classes | `Win32_PerfRawData_MSMQ_MSMQQueue`
|
| Spource | Performance Counters |
|
||||||
Enabled by default? | No
|
| Enabled by default? | No |
|
||||||
|
|
||||||
## Flags
|
## Flags
|
||||||
|
|
||||||
### `--collector.msmq.msmq-where`
|
|
||||||
|
|
||||||
A WMI filter on which queues to include. `%` is a wildcard, and can be used to match on substrings.
|
|
||||||
|
|
||||||
## Metrics
|
## Metrics
|
||||||
|
|
||||||
Name | Description | Type | Labels
|
| Name | Description | Type | Labels |
|
||||||
-----|-------------|------|-------
|
|------------------------------------------|---------------------------------|-------|--------|
|
||||||
`windows_msmq_bytes_in_journal_queue` | Size of queue journal in bytes | gauge | `name`
|
| `windows_msmq_bytes_in_journal_queue` | Size of queue journal in bytes | gauge | `name` |
|
||||||
`windows_msmq_bytes_in_queue` | Size of queue in bytes | gauge | `name`
|
| `windows_msmq_bytes_in_queue` | Size of queue in bytes | gauge | `name` |
|
||||||
`windows_msmq_messages_in_journal_queue` | Count messages in queue journal | gauge | `name`
|
| `windows_msmq_messages_in_journal_queue` | Count messages in queue journal | gauge | `name` |
|
||||||
`windows_msmq_messages_in_queue` | Count messages in queue | gauge | `name`
|
| `windows_msmq_messages_in_queue` | Count messages in queue | gauge | `name` |
|
||||||
|
|
||||||
### Example metric
|
### Example metric
|
||||||
_This collector does not yet have explained examples, we would appreciate your help adding them!_
|
_This collector does not yet have explained examples, we would appreciate your help adding them!_
|
||||||
|
|||||||
21
internal/collector/msmq/const.go
Normal file
21
internal/collector/msmq/const.go
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
// Copyright 2024 The Prometheus Authors
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package msmq
|
||||||
|
|
||||||
|
const (
|
||||||
|
BytesInJournalQueue = "Bytes in Journal Queue"
|
||||||
|
BytesInQueue = "Bytes in Queue"
|
||||||
|
MessagesInJournalQueue = "Messages in Journal Queue"
|
||||||
|
MessagesInQueue = "Messages in Queue"
|
||||||
|
)
|
||||||
@@ -3,32 +3,26 @@
|
|||||||
package msmq
|
package msmq
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/alecthomas/kingpin/v2"
|
"github.com/alecthomas/kingpin/v2"
|
||||||
"github.com/prometheus-community/windows_exporter/internal/mi"
|
"github.com/prometheus-community/windows_exporter/internal/mi"
|
||||||
|
"github.com/prometheus-community/windows_exporter/internal/perfdata"
|
||||||
"github.com/prometheus-community/windows_exporter/internal/types"
|
"github.com/prometheus-community/windows_exporter/internal/types"
|
||||||
"github.com/prometheus-community/windows_exporter/internal/utils"
|
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
)
|
)
|
||||||
|
|
||||||
const Name = "msmq"
|
const Name = "msmq"
|
||||||
|
|
||||||
type Config struct {
|
type Config struct{}
|
||||||
QueryWhereClause *string `yaml:"query_where_clause"`
|
|
||||||
}
|
|
||||||
|
|
||||||
var ConfigDefaults = Config{
|
var ConfigDefaults = Config{}
|
||||||
QueryWhereClause: utils.ToPTR(""),
|
|
||||||
}
|
|
||||||
|
|
||||||
// A Collector is a Prometheus Collector for WMI Win32_PerfRawData_MSMQ_MSMQQueue metrics.
|
// A Collector is a Prometheus Collector for WMI Win32_PerfRawData_MSMQ_MSMQQueue metrics.
|
||||||
type Collector struct {
|
type Collector struct {
|
||||||
config Config
|
config Config
|
||||||
miSession *mi.Session
|
perfDataCollector *perfdata.Collector
|
||||||
|
|
||||||
bytesInJournalQueue *prometheus.Desc
|
bytesInJournalQueue *prometheus.Desc
|
||||||
bytesInQueue *prometheus.Desc
|
bytesInQueue *prometheus.Desc
|
||||||
@@ -41,10 +35,6 @@ func New(config *Config) *Collector {
|
|||||||
config = &ConfigDefaults
|
config = &ConfigDefaults
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.QueryWhereClause == nil {
|
|
||||||
config.QueryWhereClause = ConfigDefaults.QueryWhereClause
|
|
||||||
}
|
|
||||||
|
|
||||||
c := &Collector{
|
c := &Collector{
|
||||||
config: *config,
|
config: *config,
|
||||||
}
|
}
|
||||||
@@ -52,15 +42,11 @@ func New(config *Config) *Collector {
|
|||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewWithFlags(app *kingpin.Application) *Collector {
|
func NewWithFlags(_ *kingpin.Application) *Collector {
|
||||||
c := &Collector{
|
c := &Collector{
|
||||||
config: ConfigDefaults,
|
config: ConfigDefaults,
|
||||||
}
|
}
|
||||||
|
|
||||||
app.Flag("collector.msmq.msmq-where", "WQL 'where' clause to use in WMI metrics query. "+
|
|
||||||
"Limits the response to the msmqs you specify and reduces the size of the response.").
|
|
||||||
Default(*c.config.QueryWhereClause).StringVar(c.config.QueryWhereClause)
|
|
||||||
|
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,17 +58,17 @@ func (c *Collector) Close() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Collector) Build(logger *slog.Logger, miSession *mi.Session) error {
|
func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
||||||
logger = logger.With(slog.String("collector", Name))
|
var err error
|
||||||
|
|
||||||
if miSession == nil {
|
c.perfDataCollector, err = perfdata.NewCollector("MSMQ Queue", perfdata.InstancesAll, []string{
|
||||||
return errors.New("miSession is nil")
|
BytesInJournalQueue,
|
||||||
}
|
BytesInQueue,
|
||||||
|
MessagesInJournalQueue,
|
||||||
c.miSession = miSession
|
MessagesInQueue,
|
||||||
|
})
|
||||||
if *c.config.QueryWhereClause == "" {
|
if err != nil {
|
||||||
logger.Warn("No where-clause specified for msmq collector. This will generate a very large number of metrics!")
|
return fmt.Errorf("failed to create MSMQ Queue collector: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
c.bytesInJournalQueue = prometheus.NewDesc(
|
c.bytesInJournalQueue = prometheus.NewDesc(
|
||||||
@@ -113,61 +99,41 @@ func (c *Collector) Build(logger *slog.Logger, miSession *mi.Session) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type msmqQueue struct {
|
|
||||||
Name string `mi:"Name"`
|
|
||||||
|
|
||||||
BytesInJournalQueue uint64 `mi:"BytesInJournalQueue"`
|
|
||||||
BytesInQueue uint64 `mi:"BytesInQueue"`
|
|
||||||
MessagesInJournalQueue uint64 `mi:"MessagesInJournalQueue"`
|
|
||||||
MessagesInQueue uint64 `mi:"MessagesInQueue"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Collect sends the metric values for each metric
|
// Collect sends the metric values for each metric
|
||||||
// to the provided prometheus Metric channel.
|
// to the provided prometheus Metric channel.
|
||||||
func (c *Collector) Collect(ch chan<- prometheus.Metric) error {
|
func (c *Collector) Collect(ch chan<- prometheus.Metric) error {
|
||||||
var dst []msmqQueue
|
perfData, err := c.perfDataCollector.Collect()
|
||||||
|
|
||||||
query := "SELECT * FROM Win32_PerfRawData_MSMQ_MSMQQueue"
|
|
||||||
if *c.config.QueryWhereClause != "" {
|
|
||||||
query += " WHERE " + *c.config.QueryWhereClause
|
|
||||||
}
|
|
||||||
|
|
||||||
queryExpression, err := mi.NewQuery(query)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create WMI query: %w", err)
|
return fmt.Errorf("failed to collect MSMQ Queue metrics: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := c.miSession.Query(&dst, mi.NamespaceRootCIMv2, queryExpression); err != nil {
|
for name, data := range perfData {
|
||||||
return fmt.Errorf("WMI query failed: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, msmq := range dst {
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.bytesInJournalQueue,
|
c.bytesInJournalQueue,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
float64(msmq.BytesInJournalQueue),
|
data[BytesInJournalQueue].FirstValue,
|
||||||
strings.ToLower(msmq.Name),
|
name,
|
||||||
)
|
)
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.bytesInQueue,
|
c.bytesInQueue,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
float64(msmq.BytesInQueue),
|
data[BytesInQueue].FirstValue,
|
||||||
strings.ToLower(msmq.Name),
|
name,
|
||||||
)
|
)
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.messagesInJournalQueue,
|
c.messagesInJournalQueue,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
float64(msmq.MessagesInJournalQueue),
|
data[MessagesInJournalQueue].FirstValue,
|
||||||
strings.ToLower(msmq.Name),
|
name,
|
||||||
)
|
)
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.messagesInQueue,
|
c.messagesInQueue,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
float64(msmq.MessagesInQueue),
|
data[MessagesInQueue].FirstValue,
|
||||||
strings.ToLower(msmq.Name),
|
name,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -96,19 +96,19 @@ func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
|||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
c.writeRequests = prometheus.NewDesc(
|
c.writeRequests = prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(types.Namespace, Name, "server_shares_write_requests_count"),
|
prometheus.BuildFQName(types.Namespace, Name, "server_shares_write_requests_count_total"),
|
||||||
"Writes requests on the SMB Server Share",
|
"Writes requests on the SMB Server Share",
|
||||||
[]string{"share"},
|
[]string{"share"},
|
||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
c.readRequests = prometheus.NewDesc(
|
c.readRequests = prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(types.Namespace, Name, "server_shares_read_requests_count"),
|
prometheus.BuildFQName(types.Namespace, Name, "server_shares_read_requests_count_total"),
|
||||||
"Read requests on the SMB Server Share",
|
"Read requests on the SMB Server Share",
|
||||||
[]string{"share"},
|
[]string{"share"},
|
||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
c.metadataRequests = prometheus.NewDesc(
|
c.metadataRequests = prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(types.Namespace, Name, "server_shares_metadata_requests_count"),
|
prometheus.BuildFQName(types.Namespace, Name, "server_shares_metadata_requests_count_total"),
|
||||||
"Metadata requests on the SMB Server Share",
|
"Metadata requests on the SMB Server Share",
|
||||||
[]string{"share"},
|
[]string{"share"},
|
||||||
nil,
|
nil,
|
||||||
@@ -120,7 +120,7 @@ func (c *Collector) Build(_ *slog.Logger, _ *mi.Session) error {
|
|||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
c.filesOpened = prometheus.NewDesc(
|
c.filesOpened = prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(types.Namespace, Name, "server_shares_filed_opened_count"),
|
prometheus.BuildFQName(types.Namespace, Name, "server_shares_filed_opened_count_total"),
|
||||||
"Files opened on the SMB Server Share",
|
"Files opened on the SMB Server Share",
|
||||||
[]string{"share"},
|
[]string{"share"},
|
||||||
nil,
|
nil,
|
||||||
@@ -160,21 +160,21 @@ func (c *Collector) Collect(ch chan<- prometheus.Metric) error {
|
|||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.writeRequests,
|
c.writeRequests,
|
||||||
prometheus.GaugeValue,
|
prometheus.CounterValue,
|
||||||
data[writeRequests].FirstValue,
|
data[writeRequests].FirstValue,
|
||||||
share,
|
share,
|
||||||
)
|
)
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.readRequests,
|
c.readRequests,
|
||||||
prometheus.GaugeValue,
|
prometheus.CounterValue,
|
||||||
data[readRequests].FirstValue,
|
data[readRequests].FirstValue,
|
||||||
share,
|
share,
|
||||||
)
|
)
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.metadataRequests,
|
c.metadataRequests,
|
||||||
prometheus.GaugeValue,
|
prometheus.CounterValue,
|
||||||
data[metadataRequests].FirstValue,
|
data[metadataRequests].FirstValue,
|
||||||
share,
|
share,
|
||||||
)
|
)
|
||||||
@@ -188,7 +188,7 @@ func (c *Collector) Collect(ch chan<- prometheus.Metric) error {
|
|||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.filesOpened,
|
c.filesOpened,
|
||||||
prometheus.GaugeValue,
|
prometheus.CounterValue,
|
||||||
data[filesOpened].FirstValue,
|
data[filesOpened].FirstValue,
|
||||||
share,
|
share,
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user