Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[8.x](backport #41929) [x-pack][iis] capture extra .NET CLR metrics #42118

Merged
merged 1 commit into from
Dec 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.next.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,7 @@ https://github.com/elastic/beats/compare/v8.8.1\...main[Check the HEAD diff]
- Add support for region/zone for Vertex AI service in GCP module {pull}41551[41551]
- Add support for location label as an optional configuration parameter in GCP metrics metricset. {issue}41550[41550] {pull}41626[41626]
- Add support for podman metrics in docker module. {pull}41889[41889]
- Collect .NET CLR (IIS) Memory, Exceptions and LocksAndThreads metrics {pull}41929[41929]
- Added `tier_preference`, `creation_date` and `version` fields to the `elasticsearch.index` metricset. {pull}41944[41944]
- Add `use_performance_counters` to collect CPU metrics using performance counters on Windows for `system/cpu` and `system/core` {pull}41965[41965]

Expand Down
154 changes: 154 additions & 0 deletions metricbeat/docs/fields.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -40943,6 +40943,160 @@ type: long
Number of filters per sec.


type: float

--

*`iis.application_pool.net_clr.exceptions_thrown_per_sec`*::
+
--
Number of Exceptions Thrown / sec.


type: float

--

[float]
=== memory

Memory overview.



*`iis.application_pool.net_clr.memory.bytes_in_all_heaps`*::
+
--
Number of bytes in all heaps.


type: float

--

*`iis.application_pool.net_clr.memory.gen_0_collections`*::
+
--
Number of Gen 0 Collections.


type: float

--

*`iis.application_pool.net_clr.memory.gen_1_collections`*::
+
--
Number of Gen 1 Collections.


type: float

--

*`iis.application_pool.net_clr.memory.gen_2_collections`*::
+
--
Number of Gen 2 Collections.


type: float

--

*`iis.application_pool.net_clr.memory.total_committed_bytes`*::
+
--
Number of total committed bytes.


type: float

--

*`iis.application_pool.net_clr.memory.allocated_bytes_per_sec`*::
+
--
Allocated Bytes/sec.


type: float

--

*`iis.application_pool.net_clr.memory.gen_0_heap_size`*::
+
--
Gen 0 heap size.


type: float

--

*`iis.application_pool.net_clr.memory.gen_1_heap_size`*::
+
--
Gen 1 heap size.


type: float

--

*`iis.application_pool.net_clr.memory.gen_2_heap_size`*::
+
--
Gen 2 heap size.


type: float

--

*`iis.application_pool.net_clr.memory.large_object_heap_size`*::
+
--
Large Object Heap size.


type: float

--

*`iis.application_pool.net_clr.memory.time_in_gc_perc`*::
+
--
% Time in GC.


type: float

--

[float]
=== locks_and_threads

LocksAndThreads overview.



*`iis.application_pool.net_clr.locks_and_threads.contention_rate_per_sec`*::
+
--
Contention Rate / sec.


type: float

--

*`iis.application_pool.net_clr.locks_and_threads.current_queue_length`*::
+
--
Current Queue Length.


type: float

--
Expand Down
23 changes: 22 additions & 1 deletion x-pack/metricbeat/module/iis/application_pool/_meta/data.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,28 @@
"application_pool": {
"name": "test.local",
"net_clr": {
"total_exceptions_thrown": 0
"total_exceptions_thrown": 0,
"finallys_per_sec": 0,
"exceptions_thrown_per_sec": 0,
"locks_and_threads": {
"current_queue_length": 0,
"contention_rate_per_sec": 0
},
"memory": {
"gen_2_heap_size": 0,
"large_object_heap_size": 0,
"gen_1_heap_size": 0,
"gen_1_collections": 0,
"gen_0_heap_size": 0,
"bytes_in_all_heaps": 0,
"total_committed_bytes": 0,
"gen_0_collections": 0,
"gen_2_collections": 0,
"allocated_bytes_per_sec": 0,
"time_in_gc_perc": 0
},
"filters_per_sec": 0,
"throw_to_catch_depth_per_sec": 0
},
"process": {
"handle_count": 532,
Expand Down
66 changes: 66 additions & 0 deletions x-pack/metricbeat/module/iis/application_pool/_meta/fields.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,69 @@
type: float
description: >
Number of filters per sec.
- name: exceptions_thrown_per_sec
type: float
description: >
Number of Exceptions Thrown / sec.
- name: memory
type: group
description: >
Memory overview.
fields:
- name: bytes_in_all_heaps
type: float
description: >
Number of bytes in all heaps.
- name: gen_0_collections
type: float
description: >
Number of Gen 0 Collections.
- name: gen_1_collections
type: float
description: >
Number of Gen 1 Collections.
- name: gen_2_collections
type: float
description: >
Number of Gen 2 Collections.
- name: total_committed_bytes
type: float
description: >
Number of total committed bytes.
- name: allocated_bytes_per_sec
type: float
description: >
Allocated Bytes/sec.
- name: gen_0_heap_size
type: float
description: >
Gen 0 heap size.
- name: gen_1_heap_size
type: float
description: >
Gen 1 heap size.
- name: gen_2_heap_size
type: float
description: >
Gen 2 heap size.
- name: large_object_heap_size
type: float
description: >
Large Object Heap size.
- name: time_in_gc_perc
type: float
description: >
% Time in GC.
- name: locks_and_threads
type: group
description: >
LocksAndThreads overview.
fields:
- name: contention_rate_per_sec
type: float
description: >
Contention Rate / sec.
- name: current_queue_length
type: float
description: >
Current Queue Length.
45 changes: 32 additions & 13 deletions x-pack/metricbeat/module/iis/application_pool/reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
package application_pool

import (
"errors"
"fmt"
"strings"

Expand Down Expand Up @@ -34,7 +35,6 @@ type Reader struct {
type ApplicationPool struct {
name string
workerProcessIds []int
counters map[string]string
}

// WorkerProcess struct contains the worker process details
Expand All @@ -44,21 +44,40 @@ type WorkerProcess struct {
}

var appPoolCounters = map[string]string{
"process.pid": "\\Process(w3wp*)\\ID Process",
"process.cpu_usage_perc": "\\Process(w3wp*)\\% Processor Time",
"process.handle_count": "\\Process(w3wp*)\\Handle Count",
"process.thread_count": "\\Process(w3wp*)\\Thread Count",
"process.working_set": "\\Process(w3wp*)\\Working Set",
"process.private_bytes": "\\Process(w3wp*)\\Private Bytes",
"process.virtual_bytes": "\\Process(w3wp*)\\Virtual Bytes",
"process.page_faults_per_sec": "\\Process(w3wp*)\\Page Faults/sec",
"process.io_read_operations_per_sec": "\\Process(w3wp*)\\IO Read Operations/sec",
"process.io_write_operations_per_sec": "\\Process(w3wp*)\\IO Write Operations/sec",
"process.pid": "\\Process(w3wp*)\\ID Process",
"process.cpu_usage_perc": "\\Process(w3wp*)\\% Processor Time",
"process.handle_count": "\\Process(w3wp*)\\Handle Count",
"process.thread_count": "\\Process(w3wp*)\\Thread Count",
"process.working_set": "\\Process(w3wp*)\\Working Set",
"process.private_bytes": "\\Process(w3wp*)\\Private Bytes",
"process.virtual_bytes": "\\Process(w3wp*)\\Virtual Bytes",
"process.page_faults_per_sec": "\\Process(w3wp*)\\Page Faults/sec",
"process.io_read_operations_per_sec": "\\Process(w3wp*)\\IO Read Operations/sec",
"process.io_write_operations_per_sec": "\\Process(w3wp*)\\IO Write Operations/sec",

// .NET CLR Memory
"net_clr.memory.bytes_in_all_heaps": "\\.NET CLR Memory(w3wp*)\\# Bytes in all Heaps",
"net_clr.memory.gen_0_collections": "\\.NET CLR Memory(w3wp*)\\# Gen 0 Collections",
"net_clr.memory.gen_1_collections": "\\.NET CLR Memory(w3wp*)\\# Gen 1 Collections",
"net_clr.memory.gen_2_collections": "\\.NET CLR Memory(w3wp*)\\# Gen 2 Collections",
"net_clr.memory.total_committed_bytes": "\\.NET CLR Memory(w3wp*)\\# Total committed Bytes",
"net_clr.memory.allocated_bytes_per_sec": "\\.NET CLR Memory(w3wp*)\\Allocated Bytes/sec",
"net_clr.memory.gen_0_heap_size": "\\.NET CLR Memory(w3wp*)\\Gen 0 heap size",
"net_clr.memory.gen_1_heap_size": "\\.NET CLR Memory(w3wp*)\\Gen 1 heap size",
"net_clr.memory.gen_2_heap_size": "\\.NET CLR Memory(w3wp*)\\Gen 2 heap size",
"net_clr.memory.large_object_heap_size": "\\.NET CLR Memory(w3wp*)\\Large Object Heap size",
"net_clr.memory.time_in_gc_perc": "\\.NET CLR Memory(w3wp*)\\% Time in GC",

// .NET CLR Exceptions
"net_clr.total_exceptions_thrown": "\\.NET CLR Exceptions(w3wp*)\\# of Exceps Thrown",
"net_clr.exceptions_thrown_per_sec": "\\.NET CLR Exceptions(w3wp*)\\# of Exceps Thrown / sec",
"net_clr.filters_per_sec": "\\.NET CLR Exceptions(w3wp*)\\# of Filters / sec",
"net_clr.finallys_per_sec": "\\.NET CLR Exceptions(w3wp*)\\# of Finallys / sec",
"net_clr.throw_to_catch_depth_per_sec": "\\.NET CLR Exceptions(w3wp*)\\Throw To Catch Depth / sec",

// .NET CLR LocksAndThreads
"net_clr.locks_and_threads.contention_rate_per_sec": "\\.NET CLR LocksAndThreads(w3wp*)\\Contention Rate / sec",
"net_clr.locks_and_threads.current_queue_length": "\\.NET CLR LocksAndThreads(w3wp*)\\Current Queue Length",
}

// newReader creates a new instance of Reader.
Expand Down Expand Up @@ -97,7 +116,7 @@ func (r *Reader) initAppPools() error {
for key, value := range appPoolCounters {
childQueries, err := r.query.GetCounterPaths(value)
if err != nil {
if err == pdh.PDH_CSTATUS_NO_COUNTER || err == pdh.PDH_CSTATUS_NO_COUNTERNAME || err == pdh.PDH_CSTATUS_NO_INSTANCE || err == pdh.PDH_CSTATUS_NO_OBJECT {
if errors.Is(err, pdh.PDH_CSTATUS_NO_COUNTER) || errors.Is(err, pdh.PDH_CSTATUS_NO_COUNTERNAME) || errors.Is(err, pdh.PDH_CSTATUS_NO_INSTANCE) || errors.Is(err, pdh.PDH_CSTATUS_NO_OBJECT) {
r.log.Infow("Ignoring non existent counter", "error", err,
logp.Namespace("application pool"), "query", value)
} else {
Expand Down Expand Up @@ -177,7 +196,7 @@ func (r *Reader) mapEvents(values map[string][]pdh.CounterValue) map[string]mb.E
// The counter has a negative value or the counter was successfully found, but the data returned is not valid.
// This error can occur if the counter value is less than the previous value. (Because counter values always increment, the counter value rolls over to zero when it reaches its maximum value.)
// This is not an error that stops the application from running successfully and a positive counter value should be retrieved in the later calls.
if val.Err.Error == pdh.PDH_CALC_NEGATIVE_VALUE || val.Err.Error == pdh.PDH_INVALID_DATA {
if errors.Is(val.Err.Error, pdh.PDH_CALC_NEGATIVE_VALUE) || errors.Is(val.Err.Error, pdh.PDH_INVALID_DATA) {
r.log.Debugw("Counter value retrieval returned",
"error", val.Err.Error, "cstatus", pdh.PdhErrno(val.Err.CStatus), logp.Namespace("application_pool"), "query", counterPath)
continue
Expand Down
2 changes: 1 addition & 1 deletion x-pack/metricbeat/module/iis/fields.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading