Skip to content
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,7 @@
/packages/modsecurity @elastic/integration-experience
/packages/mongodb @elastic/obs-infraobs-integrations
/packages/mongodb_atlas @elastic/obs-infraobs-integrations
/packages/mongodb_otel @elastic/obs-infraobs-integrations
/packages/mysql @elastic/obs-infraobs-integrations
/packages/mysql_enterprise @elastic/sec-windows-platform
/packages/mysql_otel @elastic/obs-infraobs-integrations
Expand Down
93 changes: 93 additions & 0 deletions packages/mongodb_otel/LICENSE.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
Elastic License 2.0

URL: https://www.elastic.co/licensing/elastic-license

## Acceptance

By using the software, you agree to all of the terms and conditions below.

## Copyright License

The licensor grants you a non-exclusive, royalty-free, worldwide,
non-sublicensable, non-transferable license to use, copy, distribute, make
available, and prepare derivative works of the software, in each case subject to
the limitations and conditions below.

## Limitations

You may not provide the software to third parties as a hosted or managed
service, where the service provides users with access to any substantial set of
the features or functionality of the software.

You may not move, change, disable, or circumvent the license key functionality
in the software, and you may not remove or obscure any functionality in the
software that is protected by the license key.

You may not alter, remove, or obscure any licensing, copyright, or other notices
of the licensor in the software. Any use of the licensor’s trademarks is subject
to applicable law.

## Patents

The licensor grants you a license, under any patent claims the licensor can
license, or becomes able to license, to make, have made, use, sell, offer for
sale, import and have imported the software, in each case subject to the
limitations and conditions in this license. This license does not cover any
patent claims that you cause to be infringed by modifications or additions to
the software. If you or your company make any written claim that the software
infringes or contributes to infringement of any patent, your patent license for
the software granted under these terms ends immediately. If your company makes
such a claim, your patent license ends immediately for work on behalf of your
company.

## Notices

You must ensure that anyone who gets a copy of any part of the software from you
also gets a copy of these terms.

If you modify the software, you must include in any modified copies of the
software prominent notices stating that you have modified the software.

## No Other Rights

These terms do not imply any licenses other than those expressly granted in
these terms.

## Termination

If you use the software in violation of these terms, such use is not licensed,
and your licenses will automatically terminate. If the licensor provides you
with a notice of your violation, and you cease all violation of this license no
later than 30 days after you receive that notice, your licenses will be
reinstated retroactively. However, if you violate these terms after such
reinstatement, any additional violation of these terms will cause your licenses
to terminate automatically and permanently.

## No Liability

*As far as the law allows, the software comes as is, without any warranty or
condition, and the licensor will not be liable to you for any damages arising
out of these terms or the use or nature of the software, under any kind of
legal claim.*

## Definitions

The **licensor** is the entity offering these terms, and the **software** is the
software the licensor makes available under these terms, including any portion
of it.

**you** refers to the individual or entity agreeing to these terms.

**your company** is any legal entity, sole proprietorship, or other kind of
organization that you work for, plus all organizations that have control over,
are under the control of, or are under common control with that
organization. **control** means ownership of substantially all the assets of an
entity, or the power to direct its management and policies by vote, contract, or
otherwise. Control can be direct or indirect.

**your licenses** are all the licenses granted to you for the software under
these terms.

**use** means anything you do with the software requiring one of your licenses.

**trademark** means trademarks, service marks, and similar rights.
284 changes: 284 additions & 0 deletions packages/mongodb_otel/_dev/shared/mongodb_otel-capacity.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,284 @@
# MongoDB OTel dashboards — metrics-mongodbreceiver.otel-default
# Data stream: metrics-mongodbreceiver.otel-default
# Filter: data_stream.dataset == "mongodbreceiver.otel"

dashboards:
# ─── Capacity ─────────────────────────────────────────────────────────
- id: mongodb_otel-capacity
name: '[MongoDB OTel] Capacity'
description: Connection utilization, memory usage, storage, and resource saturation signals.
time_range:
from: "now-1h"
to: "now"
settings:
margins: true
layout_algorithm: blocked
sync:
cursor: true
tooltips: false
colors: false
filters:
- field: data_stream.dataset
equals: mongodbreceiver.otel
controls:
- type: options
label: Server
data_view: metrics-*
field: attributes.mongodb.instance
panels:
- hide_title: true
size: {w: 48, h: 2}
links:
layout: horizontal
items:
- label: Overview
dashboard: mongodb_otel-overview
- label: Operations
dashboard: mongodb_otel-operations
- label: Capacity
dashboard: mongodb_otel-capacity
- hide_title: true
size: {w: 48, h: 12}
markdown:
content: |
## [MongoDB OTel] Capacity

This dashboard monitors MongoDB resource utilization:
- Current and available connection counts by server
- Connection utilization based on current vs available connections
- Memory usage (resident, virtual)
- Storage, data, and index sizes by database
- Cursor and session counts
- title: Current Connections
hide_title: true
size: {w: 12, h: 4}
esql:
type: metric
query: |
TS metrics-mongodbreceiver.otel-default
| WHERE data_stream.dataset == "mongodbreceiver.otel"
| WHERE metrics.mongodb.connection.count IS NOT NULL
| WHERE attributes.type == "current"
| STATS current_per_server = MAX(LAST_OVER_TIME(metrics.mongodb.connection.count))
BY resource.attributes.server.address
| STATS current = SUM(current_per_server)
primary:
field: current
label: Current Connections
format:
type: number
decimals: 0
- title: Available Connections
hide_title: true
size: {w: 12, h: 4}
esql:
type: metric
query: |
TS metrics-mongodbreceiver.otel-default
| WHERE data_stream.dataset == "mongodbreceiver.otel"
| WHERE metrics.mongodb.connection.count IS NOT NULL
| WHERE attributes.type == "available"
| STATS avail_per_server = MAX(LAST_OVER_TIME(metrics.mongodb.connection.count))
BY resource.attributes.server.address
| STATS avail = SUM(avail_per_server)
primary:
field: avail
label: Available Connections
format:
type: number
decimals: 0
- title: Resident Memory
hide_title: true
size: {w: 12, h: 4}
esql:
type: metric
query: |
TS metrics-mongodbreceiver.otel-default
| WHERE data_stream.dataset == "mongodbreceiver.otel"
| WHERE metrics.mongodb.memory.usage IS NOT NULL
| WHERE attributes.type == "resident"
| STATS resident = MAX(LAST_OVER_TIME(metrics.mongodb.memory.usage))
primary:
field: resident
label: Resident Memory
format:
type: bytes
- title: Open Cursors
hide_title: true
size: {w: 12, h: 4}
esql:
type: metric
query: |
TS metrics-mongodbreceiver.otel-default
| WHERE data_stream.dataset == "mongodbreceiver.otel"
| WHERE metrics.mongodb.cursor.count IS NOT NULL
| STATS cursors = MAX(LAST_OVER_TIME(metrics.mongodb.cursor.count))
primary:
field: cursors
label: Open Cursors
format:
type: number
decimals: 0
- title: Current Connection Utilization
size: {w: 24, h: 10}
esql:
type: gauge
query: |
TS metrics-mongodbreceiver.otel-default
| WHERE data_stream.dataset == "mongodbreceiver.otel"
| WHERE metrics.mongodb.connection.count IS NOT NULL
| STATS current_per_server = MAX(LAST_OVER_TIME(metrics.mongodb.connection.count)) WHERE attributes.type == "current",
avail_per_server = MAX(LAST_OVER_TIME(metrics.mongodb.connection.count)) WHERE attributes.type == "available"
BY resource.attributes.server.address
| STATS current = SUM(current_per_server), avail = SUM(avail_per_server)
| EVAL util = CASE((current + avail) > 0, current / (current + avail), 0),
gauge_min = 0.0, gauge_max = 1.0, gauge_goal = 0.7
| STATS ratio = MAX(util), gauge_min = MAX(gauge_min), gauge_max = MAX(gauge_max), gauge_goal = MAX(gauge_goal)
metric:
field: ratio
label: Utilization
format:
type: percent
decimals: 1
minimum:
field: gauge_min
maximum:
field: gauge_max
goal:
field: gauge_goal
appearance:
shape: arc
ticks_position: auto
color:
range_type: number
range_min: 0
range_max: 1
thresholds:
- color: "#54b399"
up_to: 0.7
- color: "#d6bf57"
up_to: 0.85
- color: "#cc5642"
up_to: 1
- title: Connection Count by Type
size: {w: 24, h: 10}
esql:
type: line
query: |
TS metrics-mongodbreceiver.otel-default
| WHERE data_stream.dataset == "mongodbreceiver.otel"
| WHERE metrics.mongodb.connection.count IS NOT NULL
| STATS conn_per_server = MAX(LAST_OVER_TIME(metrics.mongodb.connection.count))
BY time_bucket = BUCKET(@timestamp, 20, ?_tstart, ?_tend),
attributes.type,
resource.attributes.server.address
| STATS conn = SUM(conn_per_server)
BY time_bucket, attributes.type
| SORT time_bucket ASC
dimension:
field: time_bucket
data_type: date
metrics:
- field: conn
label: Connections
format:
type: number
decimals: 0
breakdown:
field: attributes.type
legend:
visible: show
position: right
- title: Memory Usage
size: {w: 48, h: 12}
esql:
type: line
query: |
TS metrics-mongodbreceiver.otel-default
| WHERE data_stream.dataset == "mongodbreceiver.otel"
| WHERE metrics.mongodb.memory.usage IS NOT NULL
| STATS mem = MAX(LAST_OVER_TIME(metrics.mongodb.memory.usage))
BY time_bucket = BUCKET(@timestamp, 20, ?_tstart, ?_tend),
attributes.type
| SORT time_bucket ASC
dimension:
field: time_bucket
data_type: date
metrics:
- field: mem
label: Bytes
format:
type: bytes
breakdown:
field: attributes.type
legend:
visible: show
position: right
- title: Storage by Database
size: {w: 48, h: 12}
esql:
type: datatable
query: |
TS metrics-mongodbreceiver.otel-default
| WHERE data_stream.dataset == "mongodbreceiver.otel"
| WHERE metrics.mongodb.storage.size IS NOT NULL
OR metrics.mongodb.data.size IS NOT NULL
OR metrics.mongodb.index.size IS NOT NULL
| STATS
storage_bytes = MAX(LAST_OVER_TIME(metrics.mongodb.storage.size)),
data_bytes = MAX(LAST_OVER_TIME(metrics.mongodb.data.size)),
index_bytes = MAX(LAST_OVER_TIME(metrics.mongodb.index.size))
BY database = attributes.db.namespace
| SORT storage_bytes DESC NULLS LAST
| LIMIT 20
breakdowns:
- field: database
label: Database
metrics:
- field: storage_bytes
label: Storage
format:
type: bytes
- field: data_bytes
label: Data
format:
type: bytes
- field: index_bytes
label: Index
format:
type: bytes
- title: Cursor and Session Count
size: {w: 48, h: 12}
esql:
type: line
query: |
TS metrics-mongodbreceiver.otel-default
| WHERE data_stream.dataset == "mongodbreceiver.otel"
| FORK (
WHERE metrics.mongodb.cursor.count IS NOT NULL
| STATS val = MAX(LAST_OVER_TIME(metrics.mongodb.cursor.count))
BY time_bucket = BUCKET(@timestamp, 20, ?_tstart, ?_tend)
| EVAL metric = "cursors"
)
(
WHERE metrics.mongodb.session.count IS NOT NULL
| STATS val = MAX(LAST_OVER_TIME(metrics.mongodb.session.count))
BY time_bucket = BUCKET(@timestamp, 20, ?_tstart, ?_tend)
| EVAL metric = "sessions"
)
| STATS val = MAX(val) BY time_bucket, metric
| SORT time_bucket ASC
dimension:
field: time_bucket
data_type: date
metrics:
- field: val
label: Count
format:
type: number
decimals: 0
breakdown:
field: metric
legend:
visible: show
position: right
Loading
Loading