2023-11-04 19:51:35 +00:00
//go:build windows
package msmq
import (
"strings"
"github.com/alecthomas/kingpin/v2"
"github.com/go-kit/log"
"github.com/go-kit/log/level"
2023-11-14 15:34:31 +00:00
"github.com/prometheus-community/windows_exporter/pkg/types"
"github.com/prometheus-community/windows_exporter/pkg/utils"
"github.com/prometheus-community/windows_exporter/pkg/wmi"
2023-11-04 19:51:35 +00:00
"github.com/prometheus/client_golang/prometheus"
)
2024-08-05 13:50:41 +00:00
const Name = "msmq"
2023-11-04 19:51:35 +00:00
type Config struct {
QueryWhereClause string ` yaml:"query_where_clause" `
}
var ConfigDefaults = Config {
QueryWhereClause : "" ,
}
2024-08-10 20:05:33 +00:00
// A Collector is a Prometheus Collector for WMI Win32_PerfRawData_MSMQ_MSMQQueue metrics.
2024-08-05 13:50:41 +00:00
type Collector struct {
2023-11-04 19:51:35 +00:00
logger log . Logger
queryWhereClause * string
2024-08-05 21:40:32 +00:00
bytesInJournalQueue * prometheus . Desc
bytesInQueue * prometheus . Desc
messagesInJournalQueue * prometheus . Desc
messagesInQueue * prometheus . Desc
2023-11-04 19:51:35 +00:00
}
2024-08-05 13:50:41 +00:00
func New ( logger log . Logger , config * Config ) * Collector {
2023-11-04 19:51:35 +00:00
if config == nil {
config = & ConfigDefaults
}
2024-08-05 13:50:41 +00:00
c := & Collector {
2023-11-04 19:51:35 +00:00
queryWhereClause : & config . QueryWhereClause ,
}
c . SetLogger ( logger )
2024-08-05 13:50:41 +00:00
2023-11-04 19:51:35 +00:00
return c
}
2024-08-05 13:50:41 +00:00
func NewWithFlags ( app * kingpin . Application ) * Collector {
return & Collector {
2023-11-04 19:51:35 +00:00
queryWhereClause : app .
2024-08-05 13:50:41 +00:00
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." ) .
2023-11-04 19:51:35 +00:00
Default ( ConfigDefaults . QueryWhereClause ) . String ( ) ,
}
}
2024-08-05 13:50:41 +00:00
func ( c * Collector ) GetName ( ) string {
2023-11-04 19:51:35 +00:00
return Name
}
2024-08-05 13:50:41 +00:00
func ( c * Collector ) SetLogger ( logger log . Logger ) {
2023-11-04 19:51:35 +00:00
c . logger = log . With ( logger , "collector" , Name )
}
2024-08-05 13:50:41 +00:00
func ( c * Collector ) GetPerfCounter ( ) ( [ ] string , error ) {
2023-11-04 19:51:35 +00:00
return [ ] string { } , nil
}
2024-08-05 13:50:41 +00:00
func ( c * Collector ) Close ( ) error {
return nil
}
func ( c * Collector ) Build ( ) error {
2023-11-14 15:34:31 +00:00
if utils . IsEmpty ( c . queryWhereClause ) {
2023-11-04 19:51:35 +00:00
_ = level . Warn ( c . logger ) . Log ( "msg" , "No where-clause specified for msmq collector. This will generate a very large number of metrics!" )
}
2024-08-05 21:40:32 +00:00
c . bytesInJournalQueue = prometheus . NewDesc (
2023-11-04 19:51:35 +00:00
prometheus . BuildFQName ( types . Namespace , Name , "bytes_in_journal_queue" ) ,
"Size of queue journal in bytes" ,
[ ] string { "name" } ,
nil ,
)
2024-08-05 21:40:32 +00:00
c . bytesInQueue = prometheus . NewDesc (
2023-11-04 19:51:35 +00:00
prometheus . BuildFQName ( types . Namespace , Name , "bytes_in_queue" ) ,
"Size of queue in bytes" ,
[ ] string { "name" } ,
nil ,
)
2024-08-05 21:40:32 +00:00
c . messagesInJournalQueue = prometheus . NewDesc (
2023-11-04 19:51:35 +00:00
prometheus . BuildFQName ( types . Namespace , Name , "messages_in_journal_queue" ) ,
"Count messages in queue journal" ,
[ ] string { "name" } ,
nil ,
)
2024-08-05 21:40:32 +00:00
c . messagesInQueue = prometheus . NewDesc (
2023-11-04 19:51:35 +00:00
prometheus . BuildFQName ( types . Namespace , Name , "messages_in_queue" ) ,
"Count messages in queue" ,
[ ] string { "name" } ,
nil ,
)
return nil
}
// Collect sends the metric values for each metric
// to the provided prometheus Metric channel.
2024-08-05 13:50:41 +00:00
func ( c * Collector ) Collect ( _ * types . ScrapeContext , ch chan <- prometheus . Metric ) error {
2024-05-11 10:05:45 +00:00
if err := c . collect ( ch ) ; err != nil {
_ = level . Error ( c . logger ) . Log ( "msg" , "failed collecting msmq metrics" , "err" , err )
2023-11-04 19:51:35 +00:00
return err
}
return nil
}
type Win32_PerfRawData_MSMQ_MSMQQueue struct {
Name string
BytesinJournalQueue uint64
BytesinQueue uint64
MessagesinJournalQueue uint64
MessagesinQueue uint64
}
2024-08-05 13:50:41 +00:00
func ( c * Collector ) collect ( ch chan <- prometheus . Metric ) error {
2023-11-04 19:51:35 +00:00
var dst [ ] Win32_PerfRawData_MSMQ_MSMQQueue
q := wmi . QueryAllWhere ( & dst , * c . queryWhereClause , c . logger )
if err := wmi . Query ( q , & dst ) ; err != nil {
2024-05-11 10:05:45 +00:00
return err
2023-11-04 19:51:35 +00:00
}
for _ , msmq := range dst {
ch <- prometheus . MustNewConstMetric (
2024-08-05 21:40:32 +00:00
c . bytesInJournalQueue ,
2023-11-04 19:51:35 +00:00
prometheus . GaugeValue ,
float64 ( msmq . BytesinJournalQueue ) ,
strings . ToLower ( msmq . Name ) ,
)
ch <- prometheus . MustNewConstMetric (
2024-08-05 21:40:32 +00:00
c . bytesInQueue ,
2023-11-04 19:51:35 +00:00
prometheus . GaugeValue ,
float64 ( msmq . BytesinQueue ) ,
strings . ToLower ( msmq . Name ) ,
)
ch <- prometheus . MustNewConstMetric (
2024-08-05 21:40:32 +00:00
c . messagesInJournalQueue ,
2023-11-04 19:51:35 +00:00
prometheus . GaugeValue ,
float64 ( msmq . MessagesinJournalQueue ) ,
strings . ToLower ( msmq . Name ) ,
)
ch <- prometheus . MustNewConstMetric (
2024-08-05 21:40:32 +00:00
c . messagesInQueue ,
2023-11-04 19:51:35 +00:00
prometheus . GaugeValue ,
float64 ( msmq . MessagesinQueue ) ,
strings . ToLower ( msmq . Name ) ,
)
}
2024-05-11 10:05:45 +00:00
return nil
2023-11-04 19:51:35 +00:00
}