Compare commits
9 Commits
reduce-mot
...
nv/clone-d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fee0c21e9c | ||
|
|
b39073a035 | ||
|
|
2c41ad5a4d | ||
|
|
0aa9045b86 | ||
|
|
ac2b843389 | ||
|
|
5d711377ec | ||
|
|
c5d0fd8966 | ||
|
|
ed04ff09ff | ||
|
|
e1e9d516ac |
@@ -1357,6 +1357,14 @@ components:
|
||||
- appservice
|
||||
- containerapp
|
||||
- aks
|
||||
- sqldatabase
|
||||
- sqldatabasemi
|
||||
- mysqlflexibleserver
|
||||
- postgresqlflexibleserver
|
||||
- mongodb
|
||||
- cosmosdb
|
||||
- cassandradb
|
||||
- redis
|
||||
type: string
|
||||
CloudintegrationtypesServiceMetadata:
|
||||
properties:
|
||||
@@ -13713,6 +13721,74 @@ paths:
|
||||
summary: Update dashboard (v2)
|
||||
tags:
|
||||
- dashboard
|
||||
/api/v2/dashboards/{id}/clone:
|
||||
post:
|
||||
deprecated: false
|
||||
description: This endpoint clones an existing v2-shape dashboard. User and integration
|
||||
dashboards can be cloned; system dashboards are rejected. The clone keeps
|
||||
the source's display name, panels, and tags, but gets a freshly generated
|
||||
unique internal name and is always created as an unlocked user dashboard owned
|
||||
by the caller.
|
||||
operationId: CloneDashboardV2
|
||||
parameters:
|
||||
- in: path
|
||||
name: id
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
"201":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
properties:
|
||||
data:
|
||||
$ref: '#/components/schemas/DashboardtypesGettableDashboardV2'
|
||||
status:
|
||||
type: string
|
||||
required:
|
||||
- status
|
||||
- data
|
||||
type: object
|
||||
description: Created
|
||||
"400":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Bad Request
|
||||
"401":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Unauthorized
|
||||
"403":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Forbidden
|
||||
"404":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Not Found
|
||||
"500":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RenderErrorResponse'
|
||||
description: Internal Server Error
|
||||
security:
|
||||
- api_key:
|
||||
- EDITOR
|
||||
- tokenizer:
|
||||
- EDITOR
|
||||
summary: Clone dashboard (v2)
|
||||
tags:
|
||||
- dashboard
|
||||
/api/v2/dashboards/{id}/lock:
|
||||
delete:
|
||||
deprecated: false
|
||||
|
||||
@@ -217,6 +217,10 @@ func (module *module) CreateV2(ctx context.Context, orgID valuer.UUID, createdBy
|
||||
return module.pkgDashboardModule.CreateV2(ctx, orgID, createdBy, creator, source, postable)
|
||||
}
|
||||
|
||||
func (module *module) CloneV2(ctx context.Context, orgID valuer.UUID, createdBy string, creator valuer.UUID, id valuer.UUID) (*dashboardtypes.DashboardV2, error) {
|
||||
return module.pkgDashboardModule.CloneV2(ctx, orgID, createdBy, creator, id)
|
||||
}
|
||||
|
||||
func (module *module) GetV2(ctx context.Context, orgID valuer.UUID, id valuer.UUID) (*dashboardtypes.DashboardV2, error) {
|
||||
return module.pkgDashboardModule.GetV2(ctx, orgID, id)
|
||||
}
|
||||
|
||||
@@ -291,6 +291,8 @@
|
||||
// Prevents the usage of specific antd components in favor of our lib
|
||||
"signoz/no-signozhq-ui-barrel": "error",
|
||||
// Forces subpath imports (@signozhq/ui/<component>) instead of the eagerly-loaded barrel
|
||||
"signoz/no-css-module-bracket-access": "warn",
|
||||
// Prevents bracket access on CSS modules (styles['kebab-case']) which fails with camelCaseOnly config
|
||||
"no-restricted-globals": [
|
||||
"error",
|
||||
{
|
||||
|
||||
@@ -2,9 +2,33 @@
|
||||
const path = require('path');
|
||||
|
||||
module.exports = {
|
||||
plugins: [path.join(__dirname, 'stylelint-rules/no-unsupported-asset-url.js')],
|
||||
plugins: [
|
||||
path.join(__dirname, 'stylelint-rules/no-unsupported-asset-url.js'),
|
||||
path.join(__dirname, 'stylelint-rules/css-modules/no-deep-nesting.js'),
|
||||
path.join(__dirname, 'stylelint-rules/css-modules/no-id-selectors.js'),
|
||||
path.join(
|
||||
__dirname,
|
||||
'stylelint-rules/css-modules/no-bare-element-selectors.js',
|
||||
),
|
||||
path.join(__dirname, 'stylelint-rules/css-modules/prefer-css-variables.js'),
|
||||
path.join(__dirname, 'stylelint-rules/css-modules/class-name-pattern.js'),
|
||||
],
|
||||
customSyntax: 'postcss-scss',
|
||||
rules: {
|
||||
// Applies to all SCSS files
|
||||
'local/no-unsupported-asset-url': true,
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
// CSS module-specific rules
|
||||
files: ['**/*.module.scss'],
|
||||
rules: {
|
||||
'local/no-deep-nesting': [true, { severity: 'warning' }],
|
||||
'local/no-id-selectors': true,
|
||||
'local/no-bare-element-selectors': true,
|
||||
'local/prefer-css-variables': [true, { severity: 'warning' }],
|
||||
'local/class-name-pattern': [true, { severity: 'warning' }],
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
@@ -23,6 +23,8 @@ You are operating within a constrained context window and strict system prompts.
|
||||
- Always add data-testid or testId (if supported) to critical/behavioral components like inputs, buttons, etc...
|
||||
- When creating test, these IDs should be used instead of finding by role.
|
||||
- Never create barrel files.
|
||||
- When writing new css, prefer CSS Modules
|
||||
- Use ./docs/css-modules-guide.md as reference on how to write good CSS Modules.
|
||||
|
||||
3. FORCED VERIFICATION: Your internal tools mark file writes as successful even if the code does not compile. You are FORBIDDEN from reporting a task as complete until you have:
|
||||
- Run `pnpm tsgo --noEmit`
|
||||
|
||||
513
frontend/docs/css-modules-guide.md
Normal file
@@ -0,0 +1,513 @@
|
||||
# CSS Modules Guide
|
||||
|
||||
## Checklist Before Committing
|
||||
|
||||
- [ ] All class names use camelCase in CSS
|
||||
- [ ] State classes use `is-`/`has-` prefix (e.g., `isActive`, `hasError`)
|
||||
- [ ] No bracket access (`styles['...']`) in JS unless verified
|
||||
- [ ] No dynamic class lookup - use explicit variant maps instead
|
||||
- [ ] No deep class nesting (max 3 class levels; pseudo-classes/elements and parent-reference selectors like `&.active`, `&#bar` are not counted)
|
||||
- [ ] No hardcoded colors - use `--l1/l2/l3-*` semantic tokens (not `--bg-*` primitives)
|
||||
- [ ] No magic numbers - use `--spacing-*` tokens
|
||||
- [ ] Typography uses `--periscope-font-size-*` or `--font-size-*` tokens
|
||||
- [ ] @signozhq/ui overrides use CSS variables, not direct class overrides
|
||||
- [ ] Global escapes only for third-party overrides
|
||||
- [ ] No ID selectors
|
||||
- [ ] No bare element selectors
|
||||
- [ ] Keyframes use `:local(@keyframes name)` to avoid global collisions
|
||||
|
||||
## Config (vite.config.ts)
|
||||
|
||||
```ts
|
||||
css: {
|
||||
modules: {
|
||||
localsConvention: 'camelCaseOnly',
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
**Critical:** `camelCaseOnly` exports ONLY camelCase keys. Original kebab-case NOT accessible.
|
||||
|
||||
## Quick Reference
|
||||
|
||||
| CSS Class | JS Access | Works? | Preferred? |
|
||||
|-----------|-----------|--------|----------------------------|
|
||||
| `.alertHistory` | `styles.alertHistory` | Yes | Yes |
|
||||
| `.alert-history` | `styles.alertHistory` | Yes | No, use `.alertHistory` |
|
||||
| `.alert-history` | `styles['alert-history']` | NO - undefined | Never, use `.alertHistory` |
|
||||
|
||||
## Bad Patterns
|
||||
|
||||
### Class Naming
|
||||
|
||||
```scss
|
||||
// BAD: Bracket access won't work
|
||||
.my-class { }
|
||||
// Then in JS: styles['my-class'] -> undefined
|
||||
|
||||
// BAD: Collision - both become same key
|
||||
.alertHistory { }
|
||||
.alert-history { } // -> styles.alertHistory (conflicts)
|
||||
|
||||
// BAD: Underscore inconsistency
|
||||
.my_class { } // -> styles.myClass (confusing)
|
||||
|
||||
// GOOD: Direct camelCase
|
||||
.alertHistory { }
|
||||
.statsCard { }
|
||||
|
||||
// GOOD: State classes with is-/has- prefix
|
||||
.isDisabled { }
|
||||
.isActive { }
|
||||
.hasError { }
|
||||
.isLoading { }
|
||||
```
|
||||
|
||||
### Nesting
|
||||
|
||||
```scss
|
||||
// BAD: Deep nesting - specificity wars, hard to override
|
||||
.container {
|
||||
.wrapper {
|
||||
.inner {
|
||||
.content { }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// BAD: Nesting creates separate classes you might not expect
|
||||
.button {
|
||||
.icon { } // -> styles.icon (separate class, not scoped under .button)
|
||||
}
|
||||
|
||||
// GOOD: Flat structure
|
||||
.container { }
|
||||
.containerWrapper { }
|
||||
.containerContent { }
|
||||
|
||||
// GOOD: Nesting only for pseudo/states
|
||||
.button {
|
||||
&:hover { }
|
||||
&:disabled { }
|
||||
&::before { }
|
||||
}
|
||||
```
|
||||
|
||||
### Global Escapes
|
||||
|
||||
```scss
|
||||
// BAD: Overusing global
|
||||
:global {
|
||||
.everything { }
|
||||
.in-here { }
|
||||
.is-global { }
|
||||
}
|
||||
|
||||
// BAD: Global without necessity
|
||||
:global(.myComponent) { } // defeats purpose of modules
|
||||
|
||||
// GOOD: Targeted global for third-party overrides
|
||||
.container {
|
||||
:global(.ant-modal-content) {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Selectors
|
||||
|
||||
```scss
|
||||
// BAD: ID selectors - not reusable
|
||||
#myComponent { }
|
||||
|
||||
// BAD: Element selectors without scope
|
||||
div { } // affects ALL divs in component
|
||||
|
||||
// BAD: Complex selectors
|
||||
.container > div + span ~ p { }
|
||||
|
||||
// GOOD: Class-only selectors
|
||||
.container { }
|
||||
.title { }
|
||||
```
|
||||
|
||||
### Variables & Values
|
||||
|
||||
```scss
|
||||
// BAD: Hardcoded colors
|
||||
.button {
|
||||
background: #1890ff;
|
||||
color: white;
|
||||
}
|
||||
|
||||
// BAD: Magic numbers
|
||||
.container {
|
||||
padding: 17px;
|
||||
margin-left: 43px;
|
||||
}
|
||||
|
||||
// GOOD: Semantic tokens (theme-aware)
|
||||
.button {
|
||||
background: var(--primary-background);
|
||||
color: var(--primary-foreground);
|
||||
}
|
||||
|
||||
.card {
|
||||
background: var(--l2-background);
|
||||
color: var(--l2-foreground);
|
||||
}
|
||||
|
||||
// GOOD: Spacing system
|
||||
.container {
|
||||
padding: var(--spacing-4);
|
||||
margin-left: var(--spacing-5);
|
||||
}
|
||||
```
|
||||
|
||||
## Design Tokens (@signozhq/design-tokens)
|
||||
|
||||
Prefer semantic tokens over hardcoded values.
|
||||
|
||||
You can read the ./node_modules/@signozhq/design-tokens/dist/style.css to find complete list of available tokens.
|
||||
|
||||
### Spacing
|
||||
|
||||
```scss
|
||||
// Spacing scale (index -> px):
|
||||
// --spacing-0=0 --spacing-1=2 --spacing-2=4 --spacing-3=6 --spacing-4=8
|
||||
// --spacing-5=10 --spacing-6=12 --spacing-7=14 --spacing-8=16 --spacing-10=20
|
||||
// --spacing-12=24 --spacing-16=32 --spacing-20=40 --spacing-24=48 --spacing-32=64
|
||||
// --spacing-40=80 --spacing-48=96 --spacing-56=112 --spacing-64=128
|
||||
// (index != px; --spacing-2 is 4px, not 2px)
|
||||
.container {
|
||||
padding: var(--spacing-4); // 8px
|
||||
gap: var(--spacing-6); // 12px
|
||||
margin-bottom: var(--spacing-8); // 16px
|
||||
}
|
||||
|
||||
// Also available: --padding-* and --margin-* (rem-based)
|
||||
// --padding-1 = 0.25rem, --padding-4 = 1rem, etc.
|
||||
```
|
||||
|
||||
### Typography
|
||||
|
||||
```scss
|
||||
// Font sizes (preferred)
|
||||
.title {
|
||||
font-size: var(--periscope-font-size-large); // 18px
|
||||
font-size: var(--periscope-font-size-medium); // 16px
|
||||
font-size: var(--periscope-font-size-base); // 13px
|
||||
font-size: var(--periscope-font-size-small); // 11px
|
||||
}
|
||||
|
||||
// Alternative scale (rem-based)
|
||||
.heading {
|
||||
font-size: var(--font-size-xl); // 1.25rem
|
||||
font-size: var(--font-size-lg); // 1.125rem
|
||||
font-size: var(--font-size-base); // 1rem
|
||||
font-size: var(--font-size-sm); // 0.875rem
|
||||
}
|
||||
|
||||
// Font weights
|
||||
.bold {
|
||||
font-weight: var(--font-weight-semibold); // 600
|
||||
font-weight: var(--font-weight-medium); // 500
|
||||
font-weight: var(--font-weight-normal); // 400
|
||||
}
|
||||
|
||||
// Line heights
|
||||
.text {
|
||||
line-height: var(--line-height-20); // 20px
|
||||
line-height: var(--line-height-24); // 24px
|
||||
}
|
||||
```
|
||||
|
||||
### Colors (Prefer Semantic Tokens)
|
||||
|
||||
Use L1/L2/L3 semantic tokens - they handle light/dark theme automatically.
|
||||
|
||||
```scss
|
||||
// BAD: Primitive tokens (fixed value across themes, won't swap on theme change)
|
||||
.card {
|
||||
background: var(--bg-ink-400);
|
||||
color: var(--text-vanilla-100);
|
||||
}
|
||||
|
||||
// GOOD: L1/L2/L3 tokens (theme-aware - swap automatically light/dark)
|
||||
.card {
|
||||
background: var(--l1-background); // base layer
|
||||
color: var(--l1-foreground); // primary text
|
||||
}
|
||||
|
||||
.panel {
|
||||
background: var(--l2-background); // elevated surface
|
||||
color: var(--l2-foreground); // secondary text
|
||||
border-color: var(--l2-border);
|
||||
}
|
||||
|
||||
.nested {
|
||||
background: var(--l3-background); // nested/inset
|
||||
color: var(--l3-foreground); // tertiary text
|
||||
}
|
||||
|
||||
// Hover states
|
||||
.card:hover {
|
||||
background: var(--l1-background-hover);
|
||||
color: var(--l1-foreground-hover);
|
||||
}
|
||||
|
||||
// Semantic action colors (also theme-aware)
|
||||
.primary {
|
||||
background: var(--primary-background);
|
||||
color: var(--primary-foreground);
|
||||
}
|
||||
|
||||
.danger {
|
||||
background: var(--danger-background);
|
||||
color: var(--danger-foreground);
|
||||
}
|
||||
|
||||
.success {
|
||||
background: var(--success-background);
|
||||
color: var(--success-foreground);
|
||||
}
|
||||
|
||||
.warning {
|
||||
background: var(--warning-background);
|
||||
color: var(--warning-foreground);
|
||||
}
|
||||
|
||||
// Accent colors (for highlights, badges, etc.)
|
||||
.accent {
|
||||
background: var(--accent-primary); // robin blue
|
||||
background: var(--accent-forest); // green
|
||||
background: var(--accent-cherry); // red
|
||||
background: var(--accent-amber); // yellow
|
||||
}
|
||||
```
|
||||
|
||||
**Token hierarchy:**
|
||||
- Primitive tokens (`--bg-*`, `--text-*`, etc.) have fixed values across themes.
|
||||
- Semantic tokens (L1/L2/L3, `--primary-*`, `--danger-*`, etc.) automatically swap based on theme.
|
||||
- L1 = base/root layer
|
||||
- L2 = elevated surfaces (cards, panels)
|
||||
- L3 = nested/inset elements
|
||||
|
||||
## Overriding @signozhq/ui Components
|
||||
|
||||
Components expose CSS variables for customization.
|
||||
|
||||
You can ensure they exist by looking at ./node_modules/@signozhq/ui/dist.
|
||||
Never write a override without confirm it exists.
|
||||
|
||||
Override via:
|
||||
|
||||
### Method 1: CSS Variables (Preferred)
|
||||
|
||||
Each component exposes `--<component>-<property>` variables:
|
||||
|
||||
```scss
|
||||
// Override Button
|
||||
.customButton {
|
||||
--button-background: var(--success-background);
|
||||
--button-border-radius: var(--radius-2);
|
||||
--button-padding: var(--spacing-4) var(--spacing-8);
|
||||
--button-font-size: var(--periscope-font-size-base);
|
||||
}
|
||||
|
||||
// Override Input
|
||||
.customInput {
|
||||
--input-height: 2.5rem;
|
||||
--input-border-color: var(--l2-border);
|
||||
--input-padding: var(--spacing-2) var(--spacing-6);
|
||||
--input-placeholder-color: var(--l3-foreground);
|
||||
}
|
||||
|
||||
// Override nested parts
|
||||
.customInput {
|
||||
--input-prefix-padding: 0 var(--spacing-4) 0 var(--spacing-6);
|
||||
--input-suffix-color: var(--accent-primary);
|
||||
}
|
||||
```
|
||||
|
||||
### Method 2: Data Attributes
|
||||
|
||||
Components use data attributes for variants/states. Target them for state-specific overrides:
|
||||
|
||||
```scss
|
||||
// Target variant
|
||||
.wrapper :global([data-variant="outlined"]) {
|
||||
--button-border-color: var(--accent-primary);
|
||||
}
|
||||
|
||||
// Target size
|
||||
.wrapper :global([data-size="sm"]) {
|
||||
--button-font-size: var(--periscope-font-size-small);
|
||||
}
|
||||
|
||||
// Target color
|
||||
.wrapper :global([data-color="destructive"]) {
|
||||
--button-background: var(--danger-background);
|
||||
}
|
||||
|
||||
// Target state (Radix patterns)
|
||||
.popover :global([data-state="open"]) {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.tooltip :global([data-side="top"]) {
|
||||
margin-bottom: var(--spacing-2);
|
||||
}
|
||||
```
|
||||
|
||||
### Common Component CSS Variables
|
||||
|
||||
**Button:**
|
||||
- `--button-background`, `--button-border-radius`, `--button-padding`
|
||||
- `--button-font-size`, `--button-height`, `--button-gap`
|
||||
- `--button-hover-background`, `--button-disabled-opacity`
|
||||
|
||||
**Input:**
|
||||
- `--input-height`, `--input-border-color`, `--input-background`
|
||||
- `--input-padding`, `--input-font-size`, `--input-placeholder-color`
|
||||
- `--input-focus-outline-color`, `--input-hover-border-color`
|
||||
- `--input-prefix-*`, `--input-suffix-*` for adornments
|
||||
|
||||
**General pattern:** `--<component>-<property>` or `--<component>-<state>-<property>`
|
||||
|
||||
## Good Patterns
|
||||
|
||||
### Structure
|
||||
|
||||
```scss
|
||||
// Flat, descriptive, component-scoped
|
||||
.alertHistory { }
|
||||
.alertHistoryHeader { }
|
||||
.alertHistoryContent { }
|
||||
.alertHistoryFooter { }
|
||||
|
||||
// State modifiers as separate classes
|
||||
.alertHistory { }
|
||||
.alertHistoryLoading { }
|
||||
.alertHistoryEmpty { }
|
||||
.alertHistoryError { }
|
||||
```
|
||||
|
||||
### Composition
|
||||
|
||||
```scss
|
||||
// GOOD: Composing styles
|
||||
.baseButton {
|
||||
padding: var(--spacing-2) var(--spacing-4);
|
||||
border-radius: var(--radius-2);
|
||||
}
|
||||
|
||||
.primaryButton {
|
||||
composes: baseButton;
|
||||
background: var(--primary-background);
|
||||
}
|
||||
```
|
||||
|
||||
### Pseudo Elements
|
||||
|
||||
```scss
|
||||
.button {
|
||||
// States
|
||||
&:hover { opacity: 0.9; }
|
||||
&:focus { outline: 2px solid var(--ring); outline-offset: 2px; }
|
||||
&:disabled { opacity: 0.5; cursor: not-allowed; }
|
||||
|
||||
// Pseudo elements
|
||||
&::before { content: ''; }
|
||||
&::after { content: ''; }
|
||||
}
|
||||
```
|
||||
|
||||
### Media Queries
|
||||
|
||||
```scss
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
@media (min-width: 768px) {
|
||||
flex-direction: row;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Keyframes (Local Scoping)
|
||||
|
||||
Without `:local()`, keyframe names are global and can clash across modules:
|
||||
|
||||
```scss
|
||||
// BAD: Global keyframe - can conflict with other modules
|
||||
@keyframes fadeIn {
|
||||
from { opacity: 0; }
|
||||
to { opacity: 1; }
|
||||
}
|
||||
|
||||
// GOOD: Locally scoped keyframe
|
||||
:local(@keyframes fadeIn) {
|
||||
from { opacity: 0; }
|
||||
to { opacity: 1; }
|
||||
}
|
||||
|
||||
.modal {
|
||||
animation: fadeIn 200ms ease;
|
||||
}
|
||||
```
|
||||
|
||||
## JS Import Patterns
|
||||
|
||||
```tsx
|
||||
// GOOD
|
||||
import styles from './Component.module.scss';
|
||||
|
||||
<div className={styles.container}>
|
||||
<span className={styles.title}>Title</span>
|
||||
</div>
|
||||
|
||||
// GOOD: Conditional classes
|
||||
<div className={`${styles.button} ${isActive ? styles.buttonActive : ''}`}>
|
||||
|
||||
// GOOD: With clsx/classnames
|
||||
<div className={clsx(styles.button, { [styles.buttonActive]: isActive })}>
|
||||
|
||||
// BAD: Bracket access (may be undefined)
|
||||
<div className={styles['button-active']}> // undefined if CSS has .button-active
|
||||
|
||||
// BAD: String interpolation for class names
|
||||
<div className={`${styles.button}-active`}> // won't work
|
||||
|
||||
// BAD: Dynamic class lookup - can't be statically analyzed
|
||||
const cls = styles[`variant${props.type}`]; // Vite can't tree-shake or type-check
|
||||
|
||||
// GOOD: Explicit map for dynamic variants
|
||||
const variantMap = {
|
||||
primary: styles.variantPrimary,
|
||||
secondary: styles.variantSecondary,
|
||||
ghost: styles.variantGhost,
|
||||
};
|
||||
const cls = variantMap[props.type];
|
||||
```
|
||||
|
||||
## Lint Rules
|
||||
|
||||
### JS/TS (oxlint)
|
||||
|
||||
| Rule | Severity | Catches |
|
||||
|------|----------|---------|
|
||||
| `signoz/no-css-module-bracket-access` | warn | `styles['kebab-case']`, dynamic access |
|
||||
|
||||
### CSS/SCSS (stylelint)
|
||||
|
||||
| Rule | Severity | Catches |
|
||||
|------|----------|---------|
|
||||
| `local/no-deep-nesting` | warning | class nesting >3 levels (pseudo-classes/elements and parent-reference selectors `&.foo`, `&#bar` not counted; configurable via `maxDepth` secondary option) |
|
||||
| `local/no-id-selectors` | error | `#id` selectors |
|
||||
| `local/no-bare-element-selectors` | error | root-level `div`, `span` etc |
|
||||
| `local/prefer-css-variables` | warning | hardcoded colors |
|
||||
| `local/class-name-pattern` | warning | kebab-case, snake_case, PascalCase |
|
||||
|
||||
Run: `pnpm lint:styles` to check CSS modules.
|
||||
@@ -192,9 +192,9 @@
|
||||
"lint-staged": "^17.0.4",
|
||||
"msw": "1.3.2",
|
||||
"orval": "8.9.1",
|
||||
"oxfmt": "0.47.0",
|
||||
"oxlint": "1.62.0",
|
||||
"oxlint-tsgolint": "0.22.1",
|
||||
"oxfmt": "0.54.0",
|
||||
"oxlint": "1.69.0",
|
||||
"oxlint-tsgolint": "0.23.0",
|
||||
"postcss": "8.5.14",
|
||||
"postcss-scss": "4.0.9",
|
||||
"react-resizable": "3.0.4",
|
||||
|
||||
144
frontend/plugins/rules/no-css-module-bracket-access.mjs
Normal file
@@ -0,0 +1,144 @@
|
||||
/**
|
||||
* Rule: no-css-module-bracket-access
|
||||
*
|
||||
* Prevents bracket access on CSS module imports that may fail with camelCaseOnly config.
|
||||
*
|
||||
* With Vite's `localsConvention: 'camelCaseOnly'`, kebab-case class names are
|
||||
* converted to camelCase and the original key is NOT exported.
|
||||
*
|
||||
* This rule catches patterns like:
|
||||
* styles['my-class'] // BAD - undefined if CSS has .my-class
|
||||
* styles['myClass'] // OK but prefer dot notation
|
||||
* styles.myClass // GOOD
|
||||
*
|
||||
* Catches:
|
||||
* - Bracket access with kebab-case strings (always fails)
|
||||
* - Bracket access with any string literal (warn - prefer dot notation)
|
||||
* - Dynamic bracket access (warn - risky)
|
||||
*/
|
||||
|
||||
const CSS_MODULE_IMPORT_NAMES = new Set([
|
||||
'styles',
|
||||
'classes',
|
||||
'css',
|
||||
'classNames',
|
||||
]);
|
||||
|
||||
function looksLikeCssModuleImport(name) {
|
||||
// Common patterns: styles, componentStyles, alertHistoryStyles
|
||||
return (
|
||||
CSS_MODULE_IMPORT_NAMES.has(name) ||
|
||||
name.endsWith('Styles') ||
|
||||
name.endsWith('Classes') ||
|
||||
name.endsWith('Css')
|
||||
);
|
||||
}
|
||||
|
||||
function isKebabCase(str) {
|
||||
return str.includes('-');
|
||||
}
|
||||
|
||||
function isSnakeCase(str) {
|
||||
return str.includes('_');
|
||||
}
|
||||
|
||||
export default {
|
||||
create(context) {
|
||||
return {
|
||||
MemberExpression(node) {
|
||||
// Only check bracket notation: styles['...']
|
||||
if (!node.computed) {
|
||||
return;
|
||||
}
|
||||
|
||||
const object = node.object;
|
||||
if (object.type !== 'Identifier') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if this looks like a CSS module import
|
||||
if (!looksLikeCssModuleImport(object.name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const property = node.property;
|
||||
|
||||
// Dynamic access: styles[variable]
|
||||
if (property.type === 'Identifier') {
|
||||
context.report({
|
||||
node,
|
||||
message: `Dynamic CSS module access '${object.name}[${property.name}]' is risky. With 'camelCaseOnly' config, kebab-case keys don't exist. Use dot notation or verify the key exists.`,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Template literal: styles[\`...\`]
|
||||
if (property.type === 'TemplateLiteral') {
|
||||
context.report({
|
||||
node,
|
||||
message: `Template literal CSS module access is risky. With 'camelCaseOnly' config, kebab-case keys don't exist. Prefer dot notation.`,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Numeric / boolean / null literal: styles[0]. Not a class lookup; ignore.
|
||||
if (property.type === 'Literal' && typeof property.value !== 'string') {
|
||||
return;
|
||||
}
|
||||
|
||||
// String literal: styles['...']
|
||||
if (property.type === 'Literal' && typeof property.value === 'string') {
|
||||
const className = property.value;
|
||||
|
||||
// Kebab-case will definitely fail
|
||||
if (isKebabCase(className)) {
|
||||
context.report({
|
||||
node,
|
||||
message: `CSS module class '${className}' uses kebab-case which won't work with 'camelCaseOnly' config. Use '${object.name}.${toCamelCase(className)}' instead.`,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Snake_case is suspicious
|
||||
if (isSnakeCase(className)) {
|
||||
context.report({
|
||||
node,
|
||||
message: `CSS module class '${className}' uses snake_case which may not work as expected. Prefer camelCase: '${object.name}.${toCamelCase(className)}'.`,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Valid camelCase but using bracket notation - prefer dot
|
||||
if (/^[a-z][a-zA-Z0-9]*$/.test(className)) {
|
||||
context.report({
|
||||
node,
|
||||
message: `Prefer dot notation: '${object.name}.${className}' instead of '${object.name}['${className}']'.`,
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Catch-all for other dynamic expressions:
|
||||
// styles['prefix' + suffix] (BinaryExpression)
|
||||
// styles[isActive && 'foo'] (LogicalExpression)
|
||||
// styles[isActive ? 'a' : 'b'] (ConditionalExpression)
|
||||
// styles[fn()] (CallExpression)
|
||||
context.report({
|
||||
node,
|
||||
message: `Dynamic CSS module access on '${object.name}' is risky. With 'camelCaseOnly' config, kebab-case keys don't exist. Use dot notation or verify each key resolves to an exported camelCase class.`,
|
||||
});
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
function toCamelCase(str) {
|
||||
return str
|
||||
.split(/[-_]/)
|
||||
.map((part, i) =>
|
||||
i === 0
|
||||
? part.toLowerCase()
|
||||
: part.charAt(0).toUpperCase() + part.slice(1).toLowerCase(),
|
||||
)
|
||||
.join('');
|
||||
}
|
||||
@@ -11,6 +11,7 @@ import noUnsupportedAssetPattern from './rules/no-unsupported-asset-pattern.mjs'
|
||||
import noRawAbsolutePath from './rules/no-raw-absolute-path.mjs';
|
||||
import noAntdComponents from './rules/no-antd-components.mjs';
|
||||
import noSignozhqUiBarrel from './rules/no-signozhq-ui-barrel.mjs';
|
||||
import noCssModuleBracketAccess from './rules/no-css-module-bracket-access.mjs';
|
||||
|
||||
export default {
|
||||
meta: {
|
||||
@@ -23,5 +24,6 @@ export default {
|
||||
'no-raw-absolute-path': noRawAbsolutePath,
|
||||
'no-antd-components': noAntdComponents,
|
||||
'no-signozhq-ui-barrel': noSignozhqUiBarrel,
|
||||
'no-css-module-bracket-access': noCssModuleBracketAccess,
|
||||
},
|
||||
};
|
||||
|
||||
413
frontend/pnpm-lock.yaml
generated
@@ -462,14 +462,14 @@ importers:
|
||||
specifier: 8.9.1
|
||||
version: 8.9.1(prettier@3.8.3)(typescript@5.9.3)
|
||||
oxfmt:
|
||||
specifier: 0.47.0
|
||||
version: 0.47.0
|
||||
specifier: 0.54.0
|
||||
version: 0.54.0
|
||||
oxlint:
|
||||
specifier: 1.62.0
|
||||
version: 1.62.0(oxlint-tsgolint@0.22.1)
|
||||
specifier: 1.69.0
|
||||
version: 1.69.0(oxlint-tsgolint@0.23.0)
|
||||
oxlint-tsgolint:
|
||||
specifier: 0.22.1
|
||||
version: 0.22.1
|
||||
specifier: 0.23.0
|
||||
version: 0.23.0
|
||||
postcss:
|
||||
specifier: 8.5.14
|
||||
version: 8.5.14
|
||||
@@ -505,7 +505,7 @@ importers:
|
||||
version: 1.6.0(react@18.2.0)
|
||||
vite-plugin-checker:
|
||||
specifier: 0.12.0
|
||||
version: 0.12.0(eslint@10.2.1(jiti@2.6.1))(meow@13.2.0)(optionator@0.9.4)(oxlint@1.62.0(oxlint-tsgolint@0.22.1))(rolldown-vite@7.3.1(@types/node@16.18.25)(esbuild@0.27.7)(jiti@2.6.1)(less@4.4.0)(sass@1.97.3)(stylus@0.62.0)(terser@5.46.2)(yaml@2.8.4))(stylelint@17.7.0(typescript@5.9.3))(typescript@5.9.3)
|
||||
version: 0.12.0(eslint@10.2.1(jiti@2.6.1))(meow@13.2.0)(optionator@0.9.4)(oxlint@1.69.0(oxlint-tsgolint@0.23.0))(rolldown-vite@7.3.1(@types/node@16.18.25)(esbuild@0.27.7)(jiti@2.6.1)(less@4.4.0)(sass@1.97.3)(stylus@0.62.0)(terser@5.46.2)(yaml@2.8.4))(stylelint@17.7.0(typescript@5.9.3))(typescript@5.9.3)
|
||||
vite-plugin-compression:
|
||||
specifier: 0.5.1
|
||||
version: 0.5.1(rolldown-vite@7.3.1(@types/node@16.18.25)(esbuild@0.27.7)(jiti@2.6.1)(less@4.4.0)(sass@1.97.3)(stylus@0.62.0)(terser@5.46.2)(yaml@2.8.4))
|
||||
@@ -2123,276 +2123,276 @@ packages:
|
||||
'@oxc-project/types@0.101.0':
|
||||
resolution: {integrity: sha512-nuFhqlUzJX+gVIPPfuE6xurd4lST3mdcWOhyK/rZO0B9XWMKm79SuszIQEnSMmmDhq1DC8WWVYGVd+6F93o1gQ==}
|
||||
|
||||
'@oxfmt/binding-android-arm-eabi@0.47.0':
|
||||
resolution: {integrity: sha512-KrMQRdMi/upr81qT4ijK6X6BNp6jqpMY7FwILQnwIy9QLc3qpnhUx5rsCLGzn4ewsCQ0CNAspN2ogmP1GXLyLw==}
|
||||
'@oxfmt/binding-android-arm-eabi@0.54.0':
|
||||
resolution: {integrity: sha512-NAtpl/SiaeU103e7/OmZw0MvUnsUUopW7hEm/ecegJg7YM0skQaA0IXEZoyTV6NUdiNPupdIUreRqUZTShbn/g==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm]
|
||||
os: [android]
|
||||
|
||||
'@oxfmt/binding-android-arm64@0.47.0':
|
||||
resolution: {integrity: sha512-r4ixS/PeUpAFKgrpDoZ5pSkthjZzVzKd95525Aazj+aOv9H4ulK5zYHGb7wFY5n5kZxHK8TbOJUZgoEb1ohddQ==}
|
||||
'@oxfmt/binding-android-arm64@0.54.0':
|
||||
resolution: {integrity: sha512-B4VZfBUlKK1rmMChsssNZbkZjE8+FzG3avMjGgMDwbGxXRoXkoeXiAZ+78Oa+eyDPHvDCiUb4zH/vmCOUSafLQ==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [android]
|
||||
|
||||
'@oxfmt/binding-darwin-arm64@0.47.0':
|
||||
resolution: {integrity: sha512-CLWxiKpMl+195cm09CuaWEhJK0CirRkoMa07aR9+9AFPat2LfIKtwx1JqxZM0MTvcMe6+adlJNdVL6jdInvq3g==}
|
||||
'@oxfmt/binding-darwin-arm64@0.54.0':
|
||||
resolution: {integrity: sha512-i02vF75b+ePsQP3tHqSxVYI5S6b8X/xqdPu7/mDHXtpgXLTYXi3jJmfHU0j+dnZZDKaYTx/ioCK7QYJmtiJR2g==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@oxfmt/binding-darwin-x64@0.47.0':
|
||||
resolution: {integrity: sha512-Xq5fjTYDC50faUeLSm0rZdBqoTgleXEdD7NpJdARtQIczkCJn3xNjMUSQQkUmh4CtxkKTNL68lytcOK3e/osgg==}
|
||||
'@oxfmt/binding-darwin-x64@0.54.0':
|
||||
resolution: {integrity: sha512-8VMFvGvooXj7mswkbrhdVZ2/sgiDaBzWpkkbtO+qGDLV4EfJd67nQadHkQC0ZNbaWA9ajXfqI6i7PZLIeDzxEQ==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@oxfmt/binding-freebsd-x64@0.47.0':
|
||||
resolution: {integrity: sha512-QOU9ZIJ52p5askcEC0QJvvr8trHAWoonul8bgISo6gYUL3s50zkqafBYcNAr9LJZQbsZtPfIWHk9+5+nUp1qJQ==}
|
||||
'@oxfmt/binding-freebsd-x64@0.54.0':
|
||||
resolution: {integrity: sha512-0cRHnp43WN1Jrc5s0BdbdKgR1XirdvHy7TAFi3JEsoEVQVJxTXMbpVd76sxXlgRswNMDhVFSJw+y7Eb8mEavFQ==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [freebsd]
|
||||
|
||||
'@oxfmt/binding-linux-arm-gnueabihf@0.47.0':
|
||||
resolution: {integrity: sha512-oJxDM1aBhPvz9gmElBv8UpxyiqhwfjcbrSxT5F0xtuUzY6dQI27/AQPIt3eu3Z5Yvn0kQl5R7MA3Z+MbnRvCBw==}
|
||||
'@oxfmt/binding-linux-arm-gnueabihf@0.54.0':
|
||||
resolution: {integrity: sha512-JyQAk3hK/OEtup7Rw6kZwfdzbKqTVD5jXXb8Xpfay29suwZyfBDMVW/bj4RqEPySYWc6zCp198pOluf8n5uYzg==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
|
||||
'@oxfmt/binding-linux-arm-musleabihf@0.47.0':
|
||||
resolution: {integrity: sha512-g8Lh50VS4ibGz2q6v7r9UZY4D0dM16SdrFYOMzhqIoCwGcai8VMIRUAcqn1/jlCsOOzUXJ741+kCeJt0cofakQ==}
|
||||
'@oxfmt/binding-linux-arm-musleabihf@0.54.0':
|
||||
resolution: {integrity: sha512-qnvLatTpM8vtvjOfcckBOzJjk+n6ce/wwpP8OFeUrD5aNLYcKyWAitwj+Rk3PK9jGanbZvKsJnv14JGQ6XqFdw==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
|
||||
'@oxfmt/binding-linux-arm64-gnu@0.47.0':
|
||||
resolution: {integrity: sha512-YrNT1vQ0asaXoRbrvYENPqmBfOQ9Xr8enPNOULeYfg44VjCcrUowFy5QZr+WawE0zyP8cH9e9Gxxg0fDEFzhcg==}
|
||||
'@oxfmt/binding-linux-arm64-gnu@0.54.0':
|
||||
resolution: {integrity: sha512-SMkhnCzIYZYDk9vw3W/80eeYKmrMpGF0Giuxt4HruFlCH7jEtnPeb3SdQKMfgYi/dgtaf+hZAb5XWPYnxqCQ3w==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@oxfmt/binding-linux-arm64-musl@0.47.0':
|
||||
resolution: {integrity: sha512-IxtQC/sbBi4ubbY+MdwdanRWrG9InQJVZqyMsBa5IUaQcnSg86gQme574HxXMC1p4bo4YhV99zQ+wNnGCvEgzw==}
|
||||
'@oxfmt/binding-linux-arm64-musl@0.54.0':
|
||||
resolution: {integrity: sha512-QrwJlBFFKnxOd95TAaszpMbZBLzMoYMpGaQTZF8oibacnF5rv8l12IhILhQRPmksWiBqg0YSe2Mnl7ayeJAHSA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@oxfmt/binding-linux-ppc64-gnu@0.47.0':
|
||||
resolution: {integrity: sha512-EWXEhOMbWO0q6eJSbu0QLkU8cKi0ljlYLngeDs2Ocu/pm1rrLwyQiYzlFbdnMRURI4w9ndr1sI9rSbhlJ5o23Q==}
|
||||
'@oxfmt/binding-linux-ppc64-gnu@0.54.0':
|
||||
resolution: {integrity: sha512-WILatiol/TUHTlhod7R09+7Az/XlhKwmY1MHfLZNmewltPWNN/EwxP2rQSHahibZ/cB8gmckEBjBOByD+5bYsQ==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@oxfmt/binding-linux-riscv64-gnu@0.47.0':
|
||||
resolution: {integrity: sha512-tZrjS11TUiDuEpRaqdk8K9F9xETRyKXfuZKmdeW+Gj7coBnm7+8sBEfyt033EAFEQSlkniAXvBLh+Qja2ioGBQ==}
|
||||
'@oxfmt/binding-linux-riscv64-gnu@0.54.0':
|
||||
resolution: {integrity: sha512-f05YMG4BH4G8S4ME6UM6fi1MnJ9094mrnvO5Pa4SJlMfWlUM+1/ZWMEF4NnjM7shZAvbHsHRuVYpUo0PHC4P9Q==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@oxfmt/binding-linux-riscv64-musl@0.47.0':
|
||||
resolution: {integrity: sha512-KBFy+2CFKUCZzYwX2ZOPQKck1vjQbz+hextuc19G4r0WRJwadfAeuQMQRQvB+Ivc8brlbOVg7et8K7E467440g==}
|
||||
'@oxfmt/binding-linux-riscv64-musl@0.54.0':
|
||||
resolution: {integrity: sha512-UfL+2hj1ClNqcCRT9s8vBU4axDpjxgVxX96G+9DYAYjoc5b0u15CJtn2jgsi9iM+EbGNc5CW1HVRgwVu76UsSA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@oxfmt/binding-linux-s390x-gnu@0.47.0':
|
||||
resolution: {integrity: sha512-REUPFKVGSiK99B+9eaPhluEVglzaoj/SMykNC5SUiV2RSsBfV5lWN7Y0iCIc251Wz3GaeAGZsJ/zj3gjarxdFg==}
|
||||
'@oxfmt/binding-linux-s390x-gnu@0.54.0':
|
||||
resolution: {integrity: sha512-3/XZe931Hka+J6NjnaqJzYpsWWxDTuRdUdwSQHnOuJEgbC+SehIMFJS8hsEjV7LBhVSL2OCnRLvbVW8O97XIyw==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@oxfmt/binding-linux-x64-gnu@0.47.0':
|
||||
resolution: {integrity: sha512-KVftVSVEDeIfRW3TIeLe3aNI/iY4m1fu5mDwHcisKMZSCMKLkrhFsjowC7o9RoqNPxbbglm2+/6KAKBIts2t0Q==}
|
||||
'@oxfmt/binding-linux-x64-gnu@0.54.0':
|
||||
resolution: {integrity: sha512-Ik93RlObtu43GbxApafayFjwYE06L6Xr08cSwpBPYbDrLp2ReZx0Jm1DqwRyYRnukUJy+rK2WaEvUQOxdytU9Q==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@oxfmt/binding-linux-x64-musl@0.47.0':
|
||||
resolution: {integrity: sha512-DTsmGEaA2860Aq5VUyDO8/MT9NFxwVL93RnRYmpMwK6DsSkThmvEpqoUDDljziEpAedMRG19SCogrNbINSbLUQ==}
|
||||
'@oxfmt/binding-linux-x64-musl@0.54.0':
|
||||
resolution: {integrity: sha512-yZcakmPlD86CNymknd7KfW+FH+qfbqJH+i0h69CYfV1+KMoVeM9UED+8+TDVoU4haxI0NxY7RPCvRLy3Sqd2Qg==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@oxfmt/binding-openharmony-arm64@0.47.0':
|
||||
resolution: {integrity: sha512-8r5BDro7fLOBoq1JXHLVSs55OlrxQhEso4HVo0TcY7OXJUPYfjPoOaYL5us+yIwqyP9rQwN+rxuiNFSmaxSuOQ==}
|
||||
'@oxfmt/binding-openharmony-arm64@0.54.0':
|
||||
resolution: {integrity: sha512-GiVBZNnEZnKu00f1jTg49nomv187d0GQX+O+ocykoLeiaALuEO+swoTehHn9TehTfi7V8H0i0e/yvUjCqnwk1w==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [openharmony]
|
||||
|
||||
'@oxfmt/binding-win32-arm64-msvc@0.47.0':
|
||||
resolution: {integrity: sha512-qtz/gzm8IjSPUlseZ0ofW8zyHLoZsuP5HTfcGGkWkUblB89JT8GNYH3ICqjbDsqsGqXum0/ZndXTFplSdXFIcg==}
|
||||
'@oxfmt/binding-win32-arm64-msvc@0.54.0':
|
||||
resolution: {integrity: sha512-J0SSB8Z1Fre2sxRolYcW6Rl1RQmKdQ2hnHyq4YJrfBRiXTObLw4DXnIVraM/UyqGqwOi7yTrQA4VT7DPxlHVKA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
|
||||
'@oxfmt/binding-win32-ia32-msvc@0.47.0':
|
||||
resolution: {integrity: sha512-5vIcdcIDE7nCx+MXN6sm8kbC4zajDB31E86rez4i45iHNH/2NjdKlJ720xcHTr3eeiMcttCGPHPhE1TjtBDGZw==}
|
||||
'@oxfmt/binding-win32-ia32-msvc@0.54.0':
|
||||
resolution: {integrity: sha512-O61UDVj8zz6yXJjkHPf05VaMLOXmEF8P5kf/N0W7AQMmd6bcQogl+KJc7rMutKTL524oE9iH32JXZClBFmEQIg==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [ia32]
|
||||
os: [win32]
|
||||
|
||||
'@oxfmt/binding-win32-x64-msvc@0.47.0':
|
||||
resolution: {integrity: sha512-Sr59Y5ms54ONBjxFeWhVlGyQcHXxcl9DxC23f6yXlRkcos7LXBLoO+KDfxexjHIOZh7cWqrWduzvUjJ+pHp8cQ==}
|
||||
'@oxfmt/binding-win32-x64-msvc@0.54.0':
|
||||
resolution: {integrity: sha512-1MDpqJPiFqxWtIHas8vkb1VZ7f7eKyTffAwmO8isxQYMaG1OFKsH666BWLeXQLO+IWNfiMssLD55hbR1lIPTqg==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@oxlint-tsgolint/darwin-arm64@0.22.1':
|
||||
resolution: {integrity: sha512-4150Lpgc1YM09GcjA6GSrra1JoPjC7aOpfywLjWEY4vW0Sd1qKzqHF1WRaiw0/qUZ40OATYdv3aRd7ipPkWQbw==}
|
||||
'@oxlint-tsgolint/darwin-arm64@0.23.0':
|
||||
resolution: {integrity: sha512-gOs9PVr2wEg4ox9z0aJo+RKhhImW86YL5N6yav8BK/rgPsIrwN/igSZ+pbRr723NFvUNKde9fgMhRA6JrXAOZw==}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@oxlint-tsgolint/darwin-x64@0.22.1':
|
||||
resolution: {integrity: sha512-vFWcPWYOgZs4HWcgS1EjUZg33NLcNfEYU49KGImmCfZWkflENrmBYV4HN/C0YeAPum6ZZ/goPSvQrB/cOD+NfA==}
|
||||
'@oxlint-tsgolint/darwin-x64@0.23.0':
|
||||
resolution: {integrity: sha512-kjJ8B+7n4tB9VJdxS5A9GdJt6/bYpzbu4lXp2uO1S3sRmCB5gDEABlGoiePNApRWaW+xqL4b4xgiE727jSLhuA==}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@oxlint-tsgolint/linux-arm64@0.22.1':
|
||||
resolution: {integrity: sha512-6LiUpP0Zir3+29FvBm7Y28q/dBjSHqTZ5MhG1Ckw4fGhI4cAvbcwXaKvbjx1TP7rRmBNOoq/M5xdpHjTb+GAew==}
|
||||
'@oxlint-tsgolint/linux-arm64@0.23.0':
|
||||
resolution: {integrity: sha512-6dCZuKNu135seMXilkRk9SpCx6i1XgmiipYGalLij5WVRX6ZYS8c4xI7preN/zv9fCXhsQclTIMDu2Y/cytTjw==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@oxlint-tsgolint/linux-x64@0.22.1':
|
||||
resolution: {integrity: sha512-fuX1hEQfpHauUbXADsfqVhRzrUrGabzGXbj5wsp2vKhV5uk/Rze8Mba9GdjFGECzvXudMGqHqxB4r6jGRdhxVA==}
|
||||
'@oxlint-tsgolint/linux-x64@0.23.0':
|
||||
resolution: {integrity: sha512-3bdilnyA7kmSTjK27rvjIjSxL5SIg3wt7vwNiRkouWB83ytssyKnuGvxSYJxgMEmFpSutzaBzcCUM2jDtPGcgA==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@oxlint-tsgolint/win32-arm64@0.22.1':
|
||||
resolution: {integrity: sha512-8SZidAj+jrbZf9ZjBEYW0tiNZ+KasqB2zgW26qdiPpQSF/DzURnPmXz651IeA9YsmbVdHGIooEHUmev6QJdquA==}
|
||||
'@oxlint-tsgolint/win32-arm64@0.23.0':
|
||||
resolution: {integrity: sha512-j+OEp44SVYiQ+ZD+uttsX7u6L9SvmbbQ77SO1pSFCcJlsVMeCk8qZsjhKfGKuT/jIA+ipOJMVs/+pqUfObBWNw==}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
|
||||
'@oxlint-tsgolint/win32-x64@0.22.1':
|
||||
resolution: {integrity: sha512-QweSk9H5lFh5Y+WUf2Kq/OAN88V6+62ZwGhP38gqdRotI90luXSMkruFTj7Q2rYrzH4ZVNaSqx7NY8JpSfIzqg==}
|
||||
'@oxlint-tsgolint/win32-x64@0.23.0':
|
||||
resolution: {integrity: sha512-5MyjFuqf+g8OUPJBSGWHJtmoWnzFJYyOg4To9WMQshZYEWig/vtu7JtJ03VWnzHv9LJkAUeApY0gVCOywFR/iQ==}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@oxlint/binding-android-arm-eabi@1.62.0':
|
||||
resolution: {integrity: sha512-pKsthNECyvJh8lPTICz6VcwVy2jOqdhhsp1rlxCkhgZR47aKvXPmaRWQDv+zlXpRae4qm1MaaTnutkaOk5aofg==}
|
||||
'@oxlint/binding-android-arm-eabi@1.69.0':
|
||||
resolution: {integrity: sha512-DKQQbD5cZ/MYfDgDI7YGyGD9FSxABlsBsYFo5p26lloob543tP9+4N3guwdXIYJN+7HSZxLe8YJuwcOWw5qnHg==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm]
|
||||
os: [android]
|
||||
|
||||
'@oxlint/binding-android-arm64@1.62.0':
|
||||
resolution: {integrity: sha512-b1AUNViByvgmR2xJDubvLIr+dSuu3uraG7bsAoKo+xrpspPvu6RIn6Fhr2JUhobfep3jwUTy18Huco6GkwdvGQ==}
|
||||
'@oxlint/binding-android-arm64@1.69.0':
|
||||
resolution: {integrity: sha512-lEhb+I5pr4inux+JFwfCa1HRq3Os7NirEFQ0H1I35SVEHPm6byX0Ah47xmRha3qi6LAkxUcxViL8o/9PivjzBg==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [android]
|
||||
|
||||
'@oxlint/binding-darwin-arm64@1.62.0':
|
||||
resolution: {integrity: sha512-iG+Tvf70UJ6otfwFYIHk36Sjq9cpPP5YLxkoggANNRtzgi3Tj3g8q6Ybqi6AtkU3+yg9QwF7bDCkCS6bbL4PCg==}
|
||||
'@oxlint/binding-darwin-arm64@1.69.0':
|
||||
resolution: {integrity: sha512-GY2YE8lOZW59BW1Ia1y+1gR0XyjrZRvVWHAr8LGeGhYHE0OQJ/7cRKXTkx1P+E9/6awEc3SX8a68SFTjh/E//A==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@oxlint/binding-darwin-x64@1.62.0':
|
||||
resolution: {integrity: sha512-oOWI6YPPr5AJUx+yIDlxmuUbQjS5gZX3OH3QisawYvsZgLiQVvZtR0rPBcJTxLWqt2ClrWg0DlSrlUiG5SQNHg==}
|
||||
'@oxlint/binding-darwin-x64@1.69.0':
|
||||
resolution: {integrity: sha512-ax1oZnOjHX3LB7myQyHEaQkDwfLb6str3/nSP6O7EVUviQGNkEGzGV0EqcBJWK+Ufwx0l4xPgyYayurvhAdl2Q==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@oxlint/binding-freebsd-x64@1.62.0':
|
||||
resolution: {integrity: sha512-dLP33T7VLCmLVv4cvjkVX+rmkcwNk2UfxmsZPNur/7BQHoQR60zJ7XLiRvNUawlzn0u8ngCa3itjEG73MAMa/w==}
|
||||
'@oxlint/binding-freebsd-x64@1.69.0':
|
||||
resolution: {integrity: sha512-kHWeHv4g2h8NY+mpCxzCtY4uerMJWTN/TSnNj1CPbakFpHEJ6cTya2wWV0pDSYWOJ2+0UiEbhn3AtXxHtsnKjg==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [freebsd]
|
||||
|
||||
'@oxlint/binding-linux-arm-gnueabihf@1.62.0':
|
||||
resolution: {integrity: sha512-fl//LWNks6qo9chNY60UDYyIwtp7a5cEx4Y/rHPjaarhuwqx6jtbzEpD5V5AqmdL4a6Y5D8zeXg5HF2Cr0QmSQ==}
|
||||
'@oxlint/binding-linux-arm-gnueabihf@1.69.0':
|
||||
resolution: {integrity: sha512-gq84vM1a1oEehXo27YCDzGVcxPsZDI1yswZwz2Da1/cbnWtrL16XZZnz0G/+gIU8edtHpfjxq5c+vWEHqJfWoQ==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
|
||||
'@oxlint/binding-linux-arm-musleabihf@1.62.0':
|
||||
resolution: {integrity: sha512-i5vkAuxvueTODV3J2dL61/TXewDHhMFKvtD156cIsk7GsdfiAu7zW7kY0NJXhKeFHeiMZIh7eFNjkPYH6J47HQ==}
|
||||
'@oxlint/binding-linux-arm-musleabihf@1.69.0':
|
||||
resolution: {integrity: sha512-kIqEa98JQ0VRyrcncxA417m2AzasqTlD+FyVT1AksjvjkqQcvm7pBWYvoW3/mpyOP2XYvi5nSCCTIe6De1yu5g==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
|
||||
'@oxlint/binding-linux-arm64-gnu@1.62.0':
|
||||
resolution: {integrity: sha512-QwN19LLuIGuOjEflSeJkZmOTfBdBMlTmW8xbMf8TZhjd//cxVNYQPq75q7oKZBJc6hRx3gY7sX0Egc8cEIFZYg==}
|
||||
'@oxlint/binding-linux-arm64-gnu@1.69.0':
|
||||
resolution: {integrity: sha512-j+xYiXozxGWx2cpjCrwwGR4awTxPFsRv3JZrv23RCogEPMc4R7UqjHW47p/RG0aRlbWiROCJ8coUfCwy0dvzHA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@oxlint/binding-linux-arm64-musl@1.62.0':
|
||||
resolution: {integrity: sha512-8eCy3FCDuWUM5hWujAv6heMvfZPbcCOU3SdQUAkixZLu5bSzOkNfirJiLGoQFO943xceOKkiQRMQNzH++jM3WA==}
|
||||
'@oxlint/binding-linux-arm64-musl@1.69.0':
|
||||
resolution: {integrity: sha512-xEPpNppTfN1l/nM7gYSf9iocscu/as+p/7vxkLeLEKnYU+09Dm+5V6IhDYDh+Uz6FajEupWwCLt5SOG0y1PCKg==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@oxlint/binding-linux-ppc64-gnu@1.62.0':
|
||||
resolution: {integrity: sha512-NjQ7K7tpTPDe9J+yq8p/s/J0E7lRCkK2uDBDqvT4XIT6f4Z0tlnr59OBg/WcrmVHER1AbrcfyxhGTXgcG8ytWg==}
|
||||
'@oxlint/binding-linux-ppc64-gnu@1.69.0':
|
||||
resolution: {integrity: sha512-Ug0+eU7HJBlek+SjklYH62IlOMirEJsdxpihH0kSqX0XdrDD4NdHpQc10fK1JC35yn6KrrcN+uYzlHD38XAf8Q==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@oxlint/binding-linux-riscv64-gnu@1.62.0':
|
||||
resolution: {integrity: sha512-oKZed9gmSwze29dEt3/Wnsv6l/Ygw/FUst+8Kfpv2SGeS/glEoTGZAMQw37SVyzFV76UTHJN2snGgxK2t2+8ow==}
|
||||
'@oxlint/binding-linux-riscv64-gnu@1.69.0':
|
||||
resolution: {integrity: sha512-iEyI3GIg0l/s3G4qy2TlaaWKdzj4PJJStwtlocpDTC00PY9hZueotf6OKUj9+yfQh0lrpBW/pLMgTztbAHKJEg==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@oxlint/binding-linux-riscv64-musl@1.62.0':
|
||||
resolution: {integrity: sha512-gBjBxQ+9lGpAYq+ELqw0w8QXsBnkZclFc7GRX2r0LnEVn3ZTEqeIKpKcGjucmp76Q53bvJD0i4qBWBhcfhSfGA==}
|
||||
'@oxlint/binding-linux-riscv64-musl@1.69.0':
|
||||
resolution: {integrity: sha512-NjHjpiI4WIKSMwuoJSZi5VToPeoYOS1FR52HLIDG6lidMdqquusgtODb4iLk0+lb1q3Z0nv2/aPRcC/olmpQGg==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@oxlint/binding-linux-s390x-gnu@1.62.0':
|
||||
resolution: {integrity: sha512-Ew2Kxs9EQ9/mbAIJ2hvocMC0wsOu6YKzStI2eFBDt+Td5O8seVC/oxgRIHqCcl5sf5ratA1nozQBAuv7tphkHg==}
|
||||
'@oxlint/binding-linux-s390x-gnu@1.69.0':
|
||||
resolution: {integrity: sha512-Ai/prDewoItkDXbp38gwGZi41DycZbUTZJ3UidwoHgQC0/DaqC2TGdtBTQLJ6hSD+SAxASzh8+/eSBPmxfOacA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@oxlint/binding-linux-x64-gnu@1.62.0':
|
||||
resolution: {integrity: sha512-5z25jcAA0gfKyVwz71A0VXgaPlocPoTAxhlv/hgoK6tlCrfoNuw7haWbDHvGMfjXhdic4EqVXGRv5XsTqFnbRQ==}
|
||||
'@oxlint/binding-linux-x64-gnu@1.69.0':
|
||||
resolution: {integrity: sha512-Gt3KHgp46mRKz4sJeaASmKvD8ayXookRw07RMf+NowhEztGGDZ7VrXpoW96XuKJLjFukWizOFVNjmYb/u7caNQ==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@oxlint/binding-linux-x64-musl@1.62.0':
|
||||
resolution: {integrity: sha512-IWpHmMB6ZDllPvqWDkG6AmXrN7JF5e/c4g/0PuURsmlK+vHoYZPB70rr4u1bn3I4LsKCSpqqfveyx6UCOC8wdg==}
|
||||
'@oxlint/binding-linux-x64-musl@1.69.0':
|
||||
resolution: {integrity: sha512-7tQhJ2+p/oHv1zcfnjYI7YVzC/7iBaVOfIvFYtxdJ5F45mWgEdrCyXZXZGfiLey5t/5JhOhsaMnnv1kAzckd7g==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@oxlint/binding-openharmony-arm64@1.62.0':
|
||||
resolution: {integrity: sha512-fjlSxxrD5pA594vkyikCS9MnPRjQawW6/BLgyTYkO+73wwPlYjkcZ7LSd974l0Q2zkHQmu4DPvJFLYA7o8xrxQ==}
|
||||
'@oxlint/binding-openharmony-arm64@1.69.0':
|
||||
resolution: {integrity: sha512-vmWz6TKp/3hfA4lksR0zHBv/6xuX1jhym6eqOjdH2DXsDDHZWcp2f0KG0VCAnlVbIrjk29G4wAWMXb/Hn1YobA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [openharmony]
|
||||
|
||||
'@oxlint/binding-win32-arm64-msvc@1.62.0':
|
||||
resolution: {integrity: sha512-EiFXr8loNS0Ul3Gu80+9nr1T8jRmnKocqmHHg16tj5ZqTgUXyb97l2rrspVHdDluyFn9JfR4PoJFdNzw4paHww==}
|
||||
'@oxlint/binding-win32-arm64-msvc@1.69.0':
|
||||
resolution: {integrity: sha512-9RExaLgmaw6IoIkU9cTpT71mLfI0xZ86iZH8x518LVsOkjquJMYqb9P7KpC8lgd1t0Dxs41p2pxynq4XR3Ttzw==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
|
||||
'@oxlint/binding-win32-ia32-msvc@1.62.0':
|
||||
resolution: {integrity: sha512-IgOFvL73li1bFgab+hThXYA0N2Xms2kV2MvZN95cebV+fmrZ9AVui1JSxfeeqRLo3CpPxKZlzhyq4G0cnaAvIw==}
|
||||
'@oxlint/binding-win32-ia32-msvc@1.69.0':
|
||||
resolution: {integrity: sha512-1907kRPF8/PrcIw1E7LMs9JbVrpgnt/MvFdss3an8oDkYNAACXzTntV3t3869ZZhMZxb2AzRGbz1pA/jdFatXA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [ia32]
|
||||
os: [win32]
|
||||
|
||||
'@oxlint/binding-win32-x64-msvc@1.62.0':
|
||||
resolution: {integrity: sha512-6hMpyDWQ2zGA1OXFKBrdYMUveUCO8UJhkO6JdwZPd78xIdHZNhjx+pib+4fC2Cljuhjyl0QwA2F3df/bs4Bp6A==}
|
||||
'@oxlint/binding-win32-x64-msvc@1.69.0':
|
||||
resolution: {integrity: sha512-w8SOXv3mT9Fi6jY8OXdXCfnvX/3KNLXGNr4HEz2TA7S4Mv/PYAOmpB8y/ge40mxvBMgGNaSaaDwZpAsQn7HtWA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
@@ -6885,24 +6885,35 @@ packages:
|
||||
overlayscrollbars@2.9.2:
|
||||
resolution: {integrity: sha512-iDT84r39i7oWP72diZN2mbJUsn/taCq568aQaIrc84S87PunBT7qtsVltAF2esk7ORTRjQDnfjVYoqqTzgs8QA==}
|
||||
|
||||
oxfmt@0.47.0:
|
||||
resolution: {integrity: sha512-OFbkbzxKCpooQEnRmpTDnuwTX8KHXzZTQ4Df/hz85fpS67Pl+lxPEFvUtin56HIIS0B1k4X8oIzTXRZPufA2CA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
hasBin: true
|
||||
|
||||
oxlint-tsgolint@0.22.1:
|
||||
resolution: {integrity: sha512-YUSGSLUnoolsu8gxISEDio3q1rtsCozwfOzASUn3DT2mR2EeQ93uEEnen7s+6LpF+lyTQFln1pQfqwBh/fsVEg==}
|
||||
hasBin: true
|
||||
|
||||
oxlint@1.62.0:
|
||||
resolution: {integrity: sha512-1uFkg6HakjsGIpW9wNdeW4/2LOHW9MEkoWjZUTUfQtIHyLIZPYt00w3Sg+H3lH+206FgBPHBbW5dVE5l2ExECQ==}
|
||||
oxfmt@0.54.0:
|
||||
resolution: {integrity: sha512-DjnMwn7smSLF+Mc2+pRItnuPftm/dkUFpY/d4+33y9TfKrsHZo8GLhmUg9BrOIUEy94Rlom1Q11N6vuhE+e0oQ==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
oxlint-tsgolint: '>=0.18.0'
|
||||
svelte: ^5.0.0
|
||||
vite-plus: '*'
|
||||
peerDependenciesMeta:
|
||||
svelte:
|
||||
optional: true
|
||||
vite-plus:
|
||||
optional: true
|
||||
|
||||
oxlint-tsgolint@0.23.0:
|
||||
resolution: {integrity: sha512-3mBv3CoPbh8dFbzfDGIWa2ytZjn2v+3EX4aKRXjIhsoGFzG8GCjfRirz3rwZf1wYbZzsNLTSgpw8VjQuWdp/jA==}
|
||||
hasBin: true
|
||||
|
||||
oxlint@1.69.0:
|
||||
resolution: {integrity: sha512-ypZkK/aDc5NQV8zIR6s2H2Tl3aNW8FmJ1m9+2qsaYuRenl8vgnHNCGwTHviWJdUQzglOlHFchgopdtGhSy17Rw==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
oxlint-tsgolint: '>=0.22.1'
|
||||
vite-plus: '*'
|
||||
peerDependenciesMeta:
|
||||
oxlint-tsgolint:
|
||||
optional: true
|
||||
vite-plus:
|
||||
optional: true
|
||||
|
||||
p-limit@2.3.0:
|
||||
resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==}
|
||||
@@ -11039,136 +11050,136 @@ snapshots:
|
||||
|
||||
'@oxc-project/types@0.101.0': {}
|
||||
|
||||
'@oxfmt/binding-android-arm-eabi@0.47.0':
|
||||
'@oxfmt/binding-android-arm-eabi@0.54.0':
|
||||
optional: true
|
||||
|
||||
'@oxfmt/binding-android-arm64@0.47.0':
|
||||
'@oxfmt/binding-android-arm64@0.54.0':
|
||||
optional: true
|
||||
|
||||
'@oxfmt/binding-darwin-arm64@0.47.0':
|
||||
'@oxfmt/binding-darwin-arm64@0.54.0':
|
||||
optional: true
|
||||
|
||||
'@oxfmt/binding-darwin-x64@0.47.0':
|
||||
'@oxfmt/binding-darwin-x64@0.54.0':
|
||||
optional: true
|
||||
|
||||
'@oxfmt/binding-freebsd-x64@0.47.0':
|
||||
'@oxfmt/binding-freebsd-x64@0.54.0':
|
||||
optional: true
|
||||
|
||||
'@oxfmt/binding-linux-arm-gnueabihf@0.47.0':
|
||||
'@oxfmt/binding-linux-arm-gnueabihf@0.54.0':
|
||||
optional: true
|
||||
|
||||
'@oxfmt/binding-linux-arm-musleabihf@0.47.0':
|
||||
'@oxfmt/binding-linux-arm-musleabihf@0.54.0':
|
||||
optional: true
|
||||
|
||||
'@oxfmt/binding-linux-arm64-gnu@0.47.0':
|
||||
'@oxfmt/binding-linux-arm64-gnu@0.54.0':
|
||||
optional: true
|
||||
|
||||
'@oxfmt/binding-linux-arm64-musl@0.47.0':
|
||||
'@oxfmt/binding-linux-arm64-musl@0.54.0':
|
||||
optional: true
|
||||
|
||||
'@oxfmt/binding-linux-ppc64-gnu@0.47.0':
|
||||
'@oxfmt/binding-linux-ppc64-gnu@0.54.0':
|
||||
optional: true
|
||||
|
||||
'@oxfmt/binding-linux-riscv64-gnu@0.47.0':
|
||||
'@oxfmt/binding-linux-riscv64-gnu@0.54.0':
|
||||
optional: true
|
||||
|
||||
'@oxfmt/binding-linux-riscv64-musl@0.47.0':
|
||||
'@oxfmt/binding-linux-riscv64-musl@0.54.0':
|
||||
optional: true
|
||||
|
||||
'@oxfmt/binding-linux-s390x-gnu@0.47.0':
|
||||
'@oxfmt/binding-linux-s390x-gnu@0.54.0':
|
||||
optional: true
|
||||
|
||||
'@oxfmt/binding-linux-x64-gnu@0.47.0':
|
||||
'@oxfmt/binding-linux-x64-gnu@0.54.0':
|
||||
optional: true
|
||||
|
||||
'@oxfmt/binding-linux-x64-musl@0.47.0':
|
||||
'@oxfmt/binding-linux-x64-musl@0.54.0':
|
||||
optional: true
|
||||
|
||||
'@oxfmt/binding-openharmony-arm64@0.47.0':
|
||||
'@oxfmt/binding-openharmony-arm64@0.54.0':
|
||||
optional: true
|
||||
|
||||
'@oxfmt/binding-win32-arm64-msvc@0.47.0':
|
||||
'@oxfmt/binding-win32-arm64-msvc@0.54.0':
|
||||
optional: true
|
||||
|
||||
'@oxfmt/binding-win32-ia32-msvc@0.47.0':
|
||||
'@oxfmt/binding-win32-ia32-msvc@0.54.0':
|
||||
optional: true
|
||||
|
||||
'@oxfmt/binding-win32-x64-msvc@0.47.0':
|
||||
'@oxfmt/binding-win32-x64-msvc@0.54.0':
|
||||
optional: true
|
||||
|
||||
'@oxlint-tsgolint/darwin-arm64@0.22.1':
|
||||
'@oxlint-tsgolint/darwin-arm64@0.23.0':
|
||||
optional: true
|
||||
|
||||
'@oxlint-tsgolint/darwin-x64@0.22.1':
|
||||
'@oxlint-tsgolint/darwin-x64@0.23.0':
|
||||
optional: true
|
||||
|
||||
'@oxlint-tsgolint/linux-arm64@0.22.1':
|
||||
'@oxlint-tsgolint/linux-arm64@0.23.0':
|
||||
optional: true
|
||||
|
||||
'@oxlint-tsgolint/linux-x64@0.22.1':
|
||||
'@oxlint-tsgolint/linux-x64@0.23.0':
|
||||
optional: true
|
||||
|
||||
'@oxlint-tsgolint/win32-arm64@0.22.1':
|
||||
'@oxlint-tsgolint/win32-arm64@0.23.0':
|
||||
optional: true
|
||||
|
||||
'@oxlint-tsgolint/win32-x64@0.22.1':
|
||||
'@oxlint-tsgolint/win32-x64@0.23.0':
|
||||
optional: true
|
||||
|
||||
'@oxlint/binding-android-arm-eabi@1.62.0':
|
||||
'@oxlint/binding-android-arm-eabi@1.69.0':
|
||||
optional: true
|
||||
|
||||
'@oxlint/binding-android-arm64@1.62.0':
|
||||
'@oxlint/binding-android-arm64@1.69.0':
|
||||
optional: true
|
||||
|
||||
'@oxlint/binding-darwin-arm64@1.62.0':
|
||||
'@oxlint/binding-darwin-arm64@1.69.0':
|
||||
optional: true
|
||||
|
||||
'@oxlint/binding-darwin-x64@1.62.0':
|
||||
'@oxlint/binding-darwin-x64@1.69.0':
|
||||
optional: true
|
||||
|
||||
'@oxlint/binding-freebsd-x64@1.62.0':
|
||||
'@oxlint/binding-freebsd-x64@1.69.0':
|
||||
optional: true
|
||||
|
||||
'@oxlint/binding-linux-arm-gnueabihf@1.62.0':
|
||||
'@oxlint/binding-linux-arm-gnueabihf@1.69.0':
|
||||
optional: true
|
||||
|
||||
'@oxlint/binding-linux-arm-musleabihf@1.62.0':
|
||||
'@oxlint/binding-linux-arm-musleabihf@1.69.0':
|
||||
optional: true
|
||||
|
||||
'@oxlint/binding-linux-arm64-gnu@1.62.0':
|
||||
'@oxlint/binding-linux-arm64-gnu@1.69.0':
|
||||
optional: true
|
||||
|
||||
'@oxlint/binding-linux-arm64-musl@1.62.0':
|
||||
'@oxlint/binding-linux-arm64-musl@1.69.0':
|
||||
optional: true
|
||||
|
||||
'@oxlint/binding-linux-ppc64-gnu@1.62.0':
|
||||
'@oxlint/binding-linux-ppc64-gnu@1.69.0':
|
||||
optional: true
|
||||
|
||||
'@oxlint/binding-linux-riscv64-gnu@1.62.0':
|
||||
'@oxlint/binding-linux-riscv64-gnu@1.69.0':
|
||||
optional: true
|
||||
|
||||
'@oxlint/binding-linux-riscv64-musl@1.62.0':
|
||||
'@oxlint/binding-linux-riscv64-musl@1.69.0':
|
||||
optional: true
|
||||
|
||||
'@oxlint/binding-linux-s390x-gnu@1.62.0':
|
||||
'@oxlint/binding-linux-s390x-gnu@1.69.0':
|
||||
optional: true
|
||||
|
||||
'@oxlint/binding-linux-x64-gnu@1.62.0':
|
||||
'@oxlint/binding-linux-x64-gnu@1.69.0':
|
||||
optional: true
|
||||
|
||||
'@oxlint/binding-linux-x64-musl@1.62.0':
|
||||
'@oxlint/binding-linux-x64-musl@1.69.0':
|
||||
optional: true
|
||||
|
||||
'@oxlint/binding-openharmony-arm64@1.62.0':
|
||||
'@oxlint/binding-openharmony-arm64@1.69.0':
|
||||
optional: true
|
||||
|
||||
'@oxlint/binding-win32-arm64-msvc@1.62.0':
|
||||
'@oxlint/binding-win32-arm64-msvc@1.69.0':
|
||||
optional: true
|
||||
|
||||
'@oxlint/binding-win32-ia32-msvc@1.62.0':
|
||||
'@oxlint/binding-win32-ia32-msvc@1.69.0':
|
||||
optional: true
|
||||
|
||||
'@oxlint/binding-win32-x64-msvc@1.62.0':
|
||||
'@oxlint/binding-win32-x64-msvc@1.69.0':
|
||||
optional: true
|
||||
|
||||
'@parcel/watcher-android-arm64@2.5.1':
|
||||
@@ -16377,61 +16388,61 @@ snapshots:
|
||||
|
||||
overlayscrollbars@2.9.2: {}
|
||||
|
||||
oxfmt@0.47.0:
|
||||
oxfmt@0.54.0:
|
||||
dependencies:
|
||||
tinypool: 2.1.0
|
||||
optionalDependencies:
|
||||
'@oxfmt/binding-android-arm-eabi': 0.47.0
|
||||
'@oxfmt/binding-android-arm64': 0.47.0
|
||||
'@oxfmt/binding-darwin-arm64': 0.47.0
|
||||
'@oxfmt/binding-darwin-x64': 0.47.0
|
||||
'@oxfmt/binding-freebsd-x64': 0.47.0
|
||||
'@oxfmt/binding-linux-arm-gnueabihf': 0.47.0
|
||||
'@oxfmt/binding-linux-arm-musleabihf': 0.47.0
|
||||
'@oxfmt/binding-linux-arm64-gnu': 0.47.0
|
||||
'@oxfmt/binding-linux-arm64-musl': 0.47.0
|
||||
'@oxfmt/binding-linux-ppc64-gnu': 0.47.0
|
||||
'@oxfmt/binding-linux-riscv64-gnu': 0.47.0
|
||||
'@oxfmt/binding-linux-riscv64-musl': 0.47.0
|
||||
'@oxfmt/binding-linux-s390x-gnu': 0.47.0
|
||||
'@oxfmt/binding-linux-x64-gnu': 0.47.0
|
||||
'@oxfmt/binding-linux-x64-musl': 0.47.0
|
||||
'@oxfmt/binding-openharmony-arm64': 0.47.0
|
||||
'@oxfmt/binding-win32-arm64-msvc': 0.47.0
|
||||
'@oxfmt/binding-win32-ia32-msvc': 0.47.0
|
||||
'@oxfmt/binding-win32-x64-msvc': 0.47.0
|
||||
'@oxfmt/binding-android-arm-eabi': 0.54.0
|
||||
'@oxfmt/binding-android-arm64': 0.54.0
|
||||
'@oxfmt/binding-darwin-arm64': 0.54.0
|
||||
'@oxfmt/binding-darwin-x64': 0.54.0
|
||||
'@oxfmt/binding-freebsd-x64': 0.54.0
|
||||
'@oxfmt/binding-linux-arm-gnueabihf': 0.54.0
|
||||
'@oxfmt/binding-linux-arm-musleabihf': 0.54.0
|
||||
'@oxfmt/binding-linux-arm64-gnu': 0.54.0
|
||||
'@oxfmt/binding-linux-arm64-musl': 0.54.0
|
||||
'@oxfmt/binding-linux-ppc64-gnu': 0.54.0
|
||||
'@oxfmt/binding-linux-riscv64-gnu': 0.54.0
|
||||
'@oxfmt/binding-linux-riscv64-musl': 0.54.0
|
||||
'@oxfmt/binding-linux-s390x-gnu': 0.54.0
|
||||
'@oxfmt/binding-linux-x64-gnu': 0.54.0
|
||||
'@oxfmt/binding-linux-x64-musl': 0.54.0
|
||||
'@oxfmt/binding-openharmony-arm64': 0.54.0
|
||||
'@oxfmt/binding-win32-arm64-msvc': 0.54.0
|
||||
'@oxfmt/binding-win32-ia32-msvc': 0.54.0
|
||||
'@oxfmt/binding-win32-x64-msvc': 0.54.0
|
||||
|
||||
oxlint-tsgolint@0.22.1:
|
||||
oxlint-tsgolint@0.23.0:
|
||||
optionalDependencies:
|
||||
'@oxlint-tsgolint/darwin-arm64': 0.22.1
|
||||
'@oxlint-tsgolint/darwin-x64': 0.22.1
|
||||
'@oxlint-tsgolint/linux-arm64': 0.22.1
|
||||
'@oxlint-tsgolint/linux-x64': 0.22.1
|
||||
'@oxlint-tsgolint/win32-arm64': 0.22.1
|
||||
'@oxlint-tsgolint/win32-x64': 0.22.1
|
||||
'@oxlint-tsgolint/darwin-arm64': 0.23.0
|
||||
'@oxlint-tsgolint/darwin-x64': 0.23.0
|
||||
'@oxlint-tsgolint/linux-arm64': 0.23.0
|
||||
'@oxlint-tsgolint/linux-x64': 0.23.0
|
||||
'@oxlint-tsgolint/win32-arm64': 0.23.0
|
||||
'@oxlint-tsgolint/win32-x64': 0.23.0
|
||||
|
||||
oxlint@1.62.0(oxlint-tsgolint@0.22.1):
|
||||
oxlint@1.69.0(oxlint-tsgolint@0.23.0):
|
||||
optionalDependencies:
|
||||
'@oxlint/binding-android-arm-eabi': 1.62.0
|
||||
'@oxlint/binding-android-arm64': 1.62.0
|
||||
'@oxlint/binding-darwin-arm64': 1.62.0
|
||||
'@oxlint/binding-darwin-x64': 1.62.0
|
||||
'@oxlint/binding-freebsd-x64': 1.62.0
|
||||
'@oxlint/binding-linux-arm-gnueabihf': 1.62.0
|
||||
'@oxlint/binding-linux-arm-musleabihf': 1.62.0
|
||||
'@oxlint/binding-linux-arm64-gnu': 1.62.0
|
||||
'@oxlint/binding-linux-arm64-musl': 1.62.0
|
||||
'@oxlint/binding-linux-ppc64-gnu': 1.62.0
|
||||
'@oxlint/binding-linux-riscv64-gnu': 1.62.0
|
||||
'@oxlint/binding-linux-riscv64-musl': 1.62.0
|
||||
'@oxlint/binding-linux-s390x-gnu': 1.62.0
|
||||
'@oxlint/binding-linux-x64-gnu': 1.62.0
|
||||
'@oxlint/binding-linux-x64-musl': 1.62.0
|
||||
'@oxlint/binding-openharmony-arm64': 1.62.0
|
||||
'@oxlint/binding-win32-arm64-msvc': 1.62.0
|
||||
'@oxlint/binding-win32-ia32-msvc': 1.62.0
|
||||
'@oxlint/binding-win32-x64-msvc': 1.62.0
|
||||
oxlint-tsgolint: 0.22.1
|
||||
'@oxlint/binding-android-arm-eabi': 1.69.0
|
||||
'@oxlint/binding-android-arm64': 1.69.0
|
||||
'@oxlint/binding-darwin-arm64': 1.69.0
|
||||
'@oxlint/binding-darwin-x64': 1.69.0
|
||||
'@oxlint/binding-freebsd-x64': 1.69.0
|
||||
'@oxlint/binding-linux-arm-gnueabihf': 1.69.0
|
||||
'@oxlint/binding-linux-arm-musleabihf': 1.69.0
|
||||
'@oxlint/binding-linux-arm64-gnu': 1.69.0
|
||||
'@oxlint/binding-linux-arm64-musl': 1.69.0
|
||||
'@oxlint/binding-linux-ppc64-gnu': 1.69.0
|
||||
'@oxlint/binding-linux-riscv64-gnu': 1.69.0
|
||||
'@oxlint/binding-linux-riscv64-musl': 1.69.0
|
||||
'@oxlint/binding-linux-s390x-gnu': 1.69.0
|
||||
'@oxlint/binding-linux-x64-gnu': 1.69.0
|
||||
'@oxlint/binding-linux-x64-musl': 1.69.0
|
||||
'@oxlint/binding-openharmony-arm64': 1.69.0
|
||||
'@oxlint/binding-win32-arm64-msvc': 1.69.0
|
||||
'@oxlint/binding-win32-ia32-msvc': 1.69.0
|
||||
'@oxlint/binding-win32-x64-msvc': 1.69.0
|
||||
oxlint-tsgolint: 0.23.0
|
||||
|
||||
p-limit@2.3.0:
|
||||
dependencies:
|
||||
@@ -18476,7 +18487,7 @@ snapshots:
|
||||
unist-util-stringify-position: 4.0.0
|
||||
vfile-message: 4.0.2
|
||||
|
||||
vite-plugin-checker@0.12.0(eslint@10.2.1(jiti@2.6.1))(meow@13.2.0)(optionator@0.9.4)(oxlint@1.62.0(oxlint-tsgolint@0.22.1))(rolldown-vite@7.3.1(@types/node@16.18.25)(esbuild@0.27.7)(jiti@2.6.1)(less@4.4.0)(sass@1.97.3)(stylus@0.62.0)(terser@5.46.2)(yaml@2.8.4))(stylelint@17.7.0(typescript@5.9.3))(typescript@5.9.3):
|
||||
vite-plugin-checker@0.12.0(eslint@10.2.1(jiti@2.6.1))(meow@13.2.0)(optionator@0.9.4)(oxlint@1.69.0(oxlint-tsgolint@0.23.0))(rolldown-vite@7.3.1(@types/node@16.18.25)(esbuild@0.27.7)(jiti@2.6.1)(less@4.4.0)(sass@1.97.3)(stylus@0.62.0)(terser@5.46.2)(yaml@2.8.4))(stylelint@17.7.0(typescript@5.9.3))(typescript@5.9.3):
|
||||
dependencies:
|
||||
'@babel/code-frame': 7.29.0
|
||||
chokidar: 4.0.3
|
||||
@@ -18491,7 +18502,7 @@ snapshots:
|
||||
eslint: 10.2.1(jiti@2.6.1)
|
||||
meow: 13.2.0
|
||||
optionator: 0.9.4
|
||||
oxlint: 1.62.0(oxlint-tsgolint@0.22.1)
|
||||
oxlint: 1.69.0(oxlint-tsgolint@0.23.0)
|
||||
stylelint: 17.7.0(typescript@5.9.3)
|
||||
typescript: 5.9.3
|
||||
|
||||
|
||||
@@ -18,6 +18,8 @@ import type {
|
||||
} from 'react-query';
|
||||
|
||||
import type {
|
||||
CloneDashboardV2201,
|
||||
CloneDashboardV2PathParameters,
|
||||
CreateDashboardV2201,
|
||||
CreatePublicDashboard201,
|
||||
CreatePublicDashboardPathParameters,
|
||||
@@ -1206,6 +1208,85 @@ export const useUpdateDashboardV2 = <
|
||||
> => {
|
||||
return useMutation(getUpdateDashboardV2MutationOptions(options));
|
||||
};
|
||||
/**
|
||||
* This endpoint clones an existing v2-shape dashboard. User and integration dashboards can be cloned; system dashboards are rejected. The clone keeps the source's display name, panels, and tags, but gets a freshly generated unique internal name and is always created as an unlocked user dashboard owned by the caller.
|
||||
* @summary Clone dashboard (v2)
|
||||
*/
|
||||
export const cloneDashboardV2 = (
|
||||
{ id }: CloneDashboardV2PathParameters,
|
||||
signal?: AbortSignal,
|
||||
) => {
|
||||
return GeneratedAPIInstance<CloneDashboardV2201>({
|
||||
url: `/api/v2/dashboards/${id}/clone`,
|
||||
method: 'POST',
|
||||
signal,
|
||||
});
|
||||
};
|
||||
|
||||
export const getCloneDashboardV2MutationOptions = <
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof cloneDashboardV2>>,
|
||||
TError,
|
||||
{ pathParams: CloneDashboardV2PathParameters },
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationOptions<
|
||||
Awaited<ReturnType<typeof cloneDashboardV2>>,
|
||||
TError,
|
||||
{ pathParams: CloneDashboardV2PathParameters },
|
||||
TContext
|
||||
> => {
|
||||
const mutationKey = ['cloneDashboardV2'];
|
||||
const { mutation: mutationOptions } = options
|
||||
? options.mutation &&
|
||||
'mutationKey' in options.mutation &&
|
||||
options.mutation.mutationKey
|
||||
? options
|
||||
: { ...options, mutation: { ...options.mutation, mutationKey } }
|
||||
: { mutation: { mutationKey } };
|
||||
|
||||
const mutationFn: MutationFunction<
|
||||
Awaited<ReturnType<typeof cloneDashboardV2>>,
|
||||
{ pathParams: CloneDashboardV2PathParameters }
|
||||
> = (props) => {
|
||||
const { pathParams } = props ?? {};
|
||||
|
||||
return cloneDashboardV2(pathParams);
|
||||
};
|
||||
|
||||
return { mutationFn, ...mutationOptions };
|
||||
};
|
||||
|
||||
export type CloneDashboardV2MutationResult = NonNullable<
|
||||
Awaited<ReturnType<typeof cloneDashboardV2>>
|
||||
>;
|
||||
|
||||
export type CloneDashboardV2MutationError = ErrorType<RenderErrorResponseDTO>;
|
||||
|
||||
/**
|
||||
* @summary Clone dashboard (v2)
|
||||
*/
|
||||
export const useCloneDashboardV2 = <
|
||||
TError = ErrorType<RenderErrorResponseDTO>,
|
||||
TContext = unknown,
|
||||
>(options?: {
|
||||
mutation?: UseMutationOptions<
|
||||
Awaited<ReturnType<typeof cloneDashboardV2>>,
|
||||
TError,
|
||||
{ pathParams: CloneDashboardV2PathParameters },
|
||||
TContext
|
||||
>;
|
||||
}): UseMutationResult<
|
||||
Awaited<ReturnType<typeof cloneDashboardV2>>,
|
||||
TError,
|
||||
{ pathParams: CloneDashboardV2PathParameters },
|
||||
TContext
|
||||
> => {
|
||||
return useMutation(getCloneDashboardV2MutationOptions(options));
|
||||
};
|
||||
/**
|
||||
* This endpoint unlocks a v2-shape dashboard. Only the dashboard's creator or an org admin may lock or unlock.
|
||||
* @summary Unlock dashboard (v2)
|
||||
|
||||
@@ -2645,6 +2645,14 @@ export enum CloudintegrationtypesServiceIDDTO {
|
||||
appservice = 'appservice',
|
||||
containerapp = 'containerapp',
|
||||
aks = 'aks',
|
||||
sqldatabase = 'sqldatabase',
|
||||
sqldatabasemi = 'sqldatabasemi',
|
||||
mysqlflexibleserver = 'mysqlflexibleserver',
|
||||
postgresqlflexibleserver = 'postgresqlflexibleserver',
|
||||
mongodb = 'mongodb',
|
||||
cosmosdb = 'cosmosdb',
|
||||
cassandradb = 'cassandradb',
|
||||
redis = 'redis',
|
||||
}
|
||||
export type CloudintegrationtypesCloudIntegrationServiceDTOAnyOf = {
|
||||
/**
|
||||
@@ -9907,6 +9915,17 @@ export type UpdateDashboardV2200 = {
|
||||
status: string;
|
||||
};
|
||||
|
||||
export type CloneDashboardV2PathParameters = {
|
||||
id: string;
|
||||
};
|
||||
export type CloneDashboardV2201 = {
|
||||
data: DashboardtypesGettableDashboardV2DTO;
|
||||
/**
|
||||
* @type string
|
||||
*/
|
||||
status: string;
|
||||
};
|
||||
|
||||
export type UnlockDashboardV2PathParameters = {
|
||||
id: string;
|
||||
};
|
||||
|
||||
@@ -90,20 +90,4 @@ describe('RouteTab component', () => {
|
||||
fireEvent.click(screen.getByRole('tab', { name: 'Tab2' }));
|
||||
expect(onChangeHandler).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('unmounts inactive tab pane content after switching', () => {
|
||||
const history = createMemoryHistory({ initialEntries: ['/tab1'] });
|
||||
render(
|
||||
<Router history={history}>
|
||||
<RouteTab history={history} routes={testRoutes} activeKey="Tab1" />
|
||||
</Router>,
|
||||
);
|
||||
|
||||
expect(screen.getByText('Dummy Component 1')).toBeInTheDocument();
|
||||
|
||||
fireEvent.click(screen.getByRole('tab', { name: 'Tab2' }));
|
||||
|
||||
expect(screen.queryByText('Dummy Component 1')).not.toBeInTheDocument();
|
||||
expect(screen.getByText('Dummy Component 2')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -59,7 +59,7 @@ function RouteTab({
|
||||
destroyInactiveTabPane
|
||||
activeKey={currentRoute?.key || activeKey}
|
||||
defaultActiveKey={currentRoute?.key || activeKey}
|
||||
animated={{ inkBar: true, tabPane: false }}
|
||||
animated
|
||||
items={items}
|
||||
tabBarExtraContent={
|
||||
showRightSection && (
|
||||
|
||||
@@ -11,7 +11,6 @@ import CreateAlertV2 from 'container/CreateAlertV2';
|
||||
import FormAlertRules, { AlertDetectionTypes } from 'container/FormAlertRules';
|
||||
import DateTimeSelector from 'container/TopNav/DateTimeSelectionV2';
|
||||
import { useGetCompositeQueryParam } from 'hooks/queryBuilder/useGetCompositeQueryParam';
|
||||
import useReducedMotion from 'hooks/useReducedMotion';
|
||||
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||
import useUrlQuery from 'hooks/useUrlQuery';
|
||||
import { AlertListTabs } from 'pages/AlertList/types';
|
||||
@@ -27,7 +26,6 @@ import './CreateAlertRule.styles.scss';
|
||||
|
||||
function CreateRules(): JSX.Element {
|
||||
const [formInstance] = Form.useForm();
|
||||
const prefersReducedMotion = useReducedMotion();
|
||||
const compositeQuery = useGetCompositeQueryParam();
|
||||
const queryParams = useUrlQuery();
|
||||
const { safeNavigate } = useSafeNavigate();
|
||||
@@ -43,7 +41,7 @@ function CreateRules(): JSX.Element {
|
||||
|
||||
useEffect(() => {
|
||||
if (isTypeSelectionMode) {
|
||||
void logEvent('Alert: New alert data source selection page visited', {});
|
||||
logEvent('Alert: New alert data source selection page visited', {});
|
||||
}
|
||||
}, [isTypeSelectionMode]);
|
||||
|
||||
@@ -189,7 +187,6 @@ function CreateRules(): JSX.Element {
|
||||
return (
|
||||
<Tabs
|
||||
destroyInactiveTabPane
|
||||
animated={!prefersReducedMotion}
|
||||
items={items}
|
||||
activeKey={AlertListTabs.ALERT_RULES}
|
||||
onChange={handleTabChange}
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
import { act, renderHook } from '@testing-library/react';
|
||||
import useReducedMotion from 'hooks/useReducedMotion';
|
||||
|
||||
type ChangeListener = (e: Partial<MediaQueryListEvent>) => void;
|
||||
|
||||
function mockMatchMedia(matches: boolean): {
|
||||
setMatches: (next: boolean) => void;
|
||||
} {
|
||||
const listeners: ChangeListener[] = [];
|
||||
let currentMatches = matches;
|
||||
|
||||
Object.defineProperty(window, 'matchMedia', {
|
||||
writable: true,
|
||||
value: jest.fn(() => ({
|
||||
get matches() {
|
||||
return currentMatches;
|
||||
},
|
||||
addEventListener: jest.fn((_: string, fn: ChangeListener) => {
|
||||
listeners.push(fn);
|
||||
}),
|
||||
removeEventListener: jest.fn(),
|
||||
})),
|
||||
});
|
||||
|
||||
return {
|
||||
setMatches: (next: boolean): void => {
|
||||
currentMatches = next;
|
||||
listeners.forEach((fn) => fn({ matches: next } as MediaQueryListEvent));
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
describe('useReducedMotion', () => {
|
||||
it('returns false when prefers-reduced-motion is not set', () => {
|
||||
mockMatchMedia(false);
|
||||
const { result } = renderHook(() => useReducedMotion());
|
||||
expect(result.current).toBe(false);
|
||||
});
|
||||
|
||||
it('returns true when prefers-reduced-motion: reduce is active', () => {
|
||||
mockMatchMedia(true);
|
||||
const { result } = renderHook(() => useReducedMotion());
|
||||
expect(result.current).toBe(true);
|
||||
});
|
||||
|
||||
it('updates when system preference changes at runtime', () => {
|
||||
const { setMatches } = mockMatchMedia(false);
|
||||
const { result } = renderHook(() => useReducedMotion());
|
||||
expect(result.current).toBe(false);
|
||||
|
||||
act(() => {
|
||||
setMatches(true);
|
||||
});
|
||||
expect(result.current).toBe(true);
|
||||
|
||||
act(() => {
|
||||
setMatches(false);
|
||||
});
|
||||
expect(result.current).toBe(false);
|
||||
});
|
||||
|
||||
it('removes event listener on unmount', () => {
|
||||
const removeEventListener = jest.fn();
|
||||
Object.defineProperty(window, 'matchMedia', {
|
||||
writable: true,
|
||||
value: jest.fn(() => ({
|
||||
matches: false,
|
||||
addEventListener: jest.fn(),
|
||||
removeEventListener,
|
||||
})),
|
||||
});
|
||||
|
||||
const { unmount } = renderHook(() => useReducedMotion());
|
||||
unmount();
|
||||
expect(removeEventListener).toHaveBeenCalledWith(
|
||||
'change',
|
||||
expect.any(Function),
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -1,20 +0,0 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
function useReducedMotion(): boolean {
|
||||
const [prefersReducedMotion, setPrefersReducedMotion] = useState<boolean>(
|
||||
() => window.matchMedia('(prefers-reduced-motion: reduce)').matches,
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)');
|
||||
const onChange = (e: MediaQueryListEvent): void => {
|
||||
setPrefersReducedMotion(e.matches);
|
||||
};
|
||||
mediaQuery.addEventListener('change', onChange);
|
||||
return (): void => mediaQuery.removeEventListener('change', onChange);
|
||||
}, []);
|
||||
|
||||
return prefersReducedMotion;
|
||||
}
|
||||
|
||||
export default useReducedMotion;
|
||||
@@ -8,7 +8,6 @@ import AllAlertRules from 'container/ListAlertRules';
|
||||
import { PlannedDowntime } from 'container/PlannedDowntime/PlannedDowntime';
|
||||
import RoutingPolicies from 'container/RoutingPolicies';
|
||||
import TriggeredAlerts from 'container/TriggeredAlerts';
|
||||
import useReducedMotion from 'hooks/useReducedMotion';
|
||||
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||
import useUrlQuery from 'hooks/useUrlQuery';
|
||||
import { GalleryVerticalEnd, Pyramid } from '@signozhq/icons';
|
||||
@@ -22,7 +21,6 @@ function AllAlertList(): JSX.Element {
|
||||
const urlQuery = useUrlQuery();
|
||||
const location = useLocation();
|
||||
const { safeNavigate } = useSafeNavigate();
|
||||
const prefersReducedMotion = useReducedMotion();
|
||||
|
||||
const tab = urlQuery.get('tab');
|
||||
const subTab = urlQuery.get('subTab');
|
||||
@@ -103,7 +101,6 @@ function AllAlertList(): JSX.Element {
|
||||
return (
|
||||
<Tabs
|
||||
destroyInactiveTabPane
|
||||
animated={!prefersReducedMotion}
|
||||
items={items}
|
||||
activeKey={tab || AlertListTabs.ALERT_RULES}
|
||||
onChange={(tab): void => {
|
||||
|
||||
@@ -5,7 +5,6 @@ import DBCall from 'container/MetricsApplication/Tabs/DBCall';
|
||||
import External from 'container/MetricsApplication/Tabs/External';
|
||||
import Overview from 'container/MetricsApplication/Tabs/Overview';
|
||||
import ResourceAttributesFilter from 'container/ResourceAttributesFilter';
|
||||
import useReducedMotion from 'hooks/useReducedMotion';
|
||||
import { useSafeNavigate } from 'hooks/useSafeNavigate';
|
||||
import useUrlQuery from 'hooks/useUrlQuery';
|
||||
|
||||
@@ -21,7 +20,6 @@ function MetricsApplication(): JSX.Element {
|
||||
}>();
|
||||
|
||||
const activeKey = useMetricsApplicationTabKey();
|
||||
const prefersReducedMotion = useReducedMotion();
|
||||
|
||||
const urlQuery = useUrlQuery();
|
||||
const { safeNavigate } = useSafeNavigate();
|
||||
@@ -58,7 +56,6 @@ function MetricsApplication(): JSX.Element {
|
||||
activeKey={activeKey}
|
||||
className="service-route-tab"
|
||||
destroyInactiveTabPane
|
||||
animated={!prefersReducedMotion}
|
||||
onChange={onTabChange}
|
||||
/>
|
||||
</div>
|
||||
|
||||
186
frontend/stylelint-rules/css-modules/class-name-pattern.js
Normal file
@@ -0,0 +1,186 @@
|
||||
/**
|
||||
* Stylelint rule: local/class-name-pattern
|
||||
*
|
||||
* Enforces camelCase class names in CSS modules.
|
||||
* With Vite's `localsConvention: 'camelCaseOnly'`, kebab-case is converted but
|
||||
* using camelCase directly avoids confusion.
|
||||
*
|
||||
* BAD:
|
||||
* .my-class { } // converted to myClass, but confusing
|
||||
* .my_class { } // converted to myClass, but confusing
|
||||
* .MyClass { } // PascalCase not conventional
|
||||
*
|
||||
* GOOD:
|
||||
* .myClass { }
|
||||
* .alertHistory { }
|
||||
* .statsCard { }
|
||||
*/
|
||||
import stylelint from 'stylelint';
|
||||
|
||||
const ruleName = 'local/class-name-pattern';
|
||||
|
||||
const messages = stylelint.utils.ruleMessages(ruleName, {
|
||||
kebabCase: (className) =>
|
||||
`Class "${className}" is not on camelCase. Use instead: "${toCamelCase(className)}".`,
|
||||
snakeCase: (className) =>
|
||||
`Class "${className}" is not on camelCase. Use instead: "${toCamelCase(className)}".`,
|
||||
pascalCase: (className) =>
|
||||
`Class "${className}" is not on camelCase. Use instead: "${className.charAt(0).toLowerCase() + className.slice(1)}".`,
|
||||
});
|
||||
|
||||
function toCamelCase(str) {
|
||||
return str
|
||||
.split(/[-_]/)
|
||||
.map((part, i) =>
|
||||
i === 0
|
||||
? part.toLowerCase()
|
||||
: part.charAt(0).toUpperCase() + part.slice(1).toLowerCase(),
|
||||
)
|
||||
.join('');
|
||||
}
|
||||
|
||||
function isKebabCase(str) {
|
||||
return str.includes('-');
|
||||
}
|
||||
|
||||
function isSnakeCase(str) {
|
||||
return str.includes('_');
|
||||
}
|
||||
|
||||
function isPascalCase(str) {
|
||||
return /^[A-Z][a-zA-Z0-9]*$/.test(str);
|
||||
}
|
||||
|
||||
const CLASS_PATTERN = /\.([a-zA-Z_][a-zA-Z0-9_-]*)/g;
|
||||
|
||||
const DEFAULT_THIRD_PARTY_PREFIXES = [
|
||||
'ant-', // Ant Design
|
||||
'rc-', // rc-components (Ant Design internals)
|
||||
'recharts-', // Recharts
|
||||
'uplot-', // uPlot
|
||||
'u-', // uPlot legacy
|
||||
'leaflet-', // Leaflet
|
||||
'monaco-', // Monaco editor
|
||||
'react-resizable', // react-resizable
|
||||
'cm-', // CodeMirror
|
||||
];
|
||||
|
||||
// Bare `:global { ... }` block (no parens) makes all descendants global.
|
||||
// `:global(.foo)` is a per-selector escape — handled separately by globalRanges().
|
||||
function hasBareGlobalAncestor(node) {
|
||||
let current = node.parent;
|
||||
while (current) {
|
||||
const selector = current.selector;
|
||||
if (selector && /:global(?!\s*\()/.test(selector)) {
|
||||
return true;
|
||||
}
|
||||
current = current.parent;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Return list of [start, end) index ranges inside `selector` that fall within a
|
||||
// balanced `:global(...)` argument list. Class matches inside these ranges are
|
||||
// third-party and should be skipped.
|
||||
function globalRanges(selector) {
|
||||
const ranges = [];
|
||||
const re = /:global\s*\(/g;
|
||||
let match;
|
||||
while ((match = re.exec(selector)) !== null) {
|
||||
const argStart = match.index + match[0].length;
|
||||
let depth = 1;
|
||||
let i = argStart;
|
||||
while (i < selector.length && depth > 0) {
|
||||
const ch = selector[i];
|
||||
if (ch === '(') {
|
||||
depth++;
|
||||
} else if (ch === ')') {
|
||||
depth--;
|
||||
}
|
||||
if (depth > 0) {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
ranges.push([argStart, i]);
|
||||
re.lastIndex = i;
|
||||
}
|
||||
return ranges;
|
||||
}
|
||||
|
||||
function indexInRanges(index, ranges) {
|
||||
for (const [start, end] of ranges) {
|
||||
if (index >= start && index < end) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const rule = (primaryOption, secondaryOptions) => {
|
||||
return (root, result) => {
|
||||
if (!primaryOption) {
|
||||
return;
|
||||
}
|
||||
|
||||
const userPrefixes =
|
||||
(secondaryOptions && secondaryOptions.ignoreThirdPartyPrefixes) || [];
|
||||
const allPrefixes = [...DEFAULT_THIRD_PARTY_PREFIXES, ...userPrefixes];
|
||||
|
||||
root.walkRules((ruleNode) => {
|
||||
const selector = ruleNode.selector;
|
||||
|
||||
// Bare `:global { }` block makes all descendants global — skip entirely.
|
||||
if (hasBareGlobalAncestor(ruleNode)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const ranges = globalRanges(selector);
|
||||
|
||||
let match;
|
||||
CLASS_PATTERN.lastIndex = 0;
|
||||
|
||||
while ((match = CLASS_PATTERN.exec(selector)) !== null) {
|
||||
const className = match[1];
|
||||
// Skip classes inside `:global(...)` ranges of this selector.
|
||||
if (indexInRanges(match.index, ranges)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip third-party library classes
|
||||
if (allPrefixes.some((prefix) => className.startsWith(prefix))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isKebabCase(className)) {
|
||||
stylelint.utils.report({
|
||||
message: messages.kebabCase(className),
|
||||
node: ruleNode,
|
||||
result,
|
||||
ruleName,
|
||||
});
|
||||
} else if (isSnakeCase(className)) {
|
||||
stylelint.utils.report({
|
||||
message: messages.snakeCase(className),
|
||||
node: ruleNode,
|
||||
result,
|
||||
ruleName,
|
||||
});
|
||||
} else if (isPascalCase(className)) {
|
||||
stylelint.utils.report({
|
||||
message: messages.pascalCase(className),
|
||||
node: ruleNode,
|
||||
result,
|
||||
ruleName,
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
rule.ruleName = ruleName;
|
||||
rule.messages = messages;
|
||||
rule.meta = {};
|
||||
|
||||
export { ruleName, rule };
|
||||
export default { ruleName, rule };
|
||||
@@ -0,0 +1,164 @@
|
||||
/**
|
||||
* Stylelint rule: local/no-bare-element-selectors
|
||||
*
|
||||
* Prevents bare element selectors at root level in CSS modules.
|
||||
* Bare elements affect ALL instances of that element within component scope,
|
||||
* often unintentionally.
|
||||
*
|
||||
* BAD:
|
||||
* div { }
|
||||
* span { padding: 4px; }
|
||||
* p { margin: 0; }
|
||||
*
|
||||
* GOOD:
|
||||
* .container { }
|
||||
* .title { }
|
||||
*
|
||||
* ALLOWED (nested under class):
|
||||
* .container {
|
||||
* p { margin: 0; } // Scoped to .container
|
||||
* }
|
||||
*/
|
||||
import stylelint from 'stylelint';
|
||||
|
||||
const ruleName = 'local/no-bare-element-selectors';
|
||||
|
||||
const messages = stylelint.utils.ruleMessages(ruleName, {
|
||||
unexpected: (element) =>
|
||||
`Bare element selector "${element}" at root level affects all instances. Use class selector or nest under a class.`,
|
||||
unexpectedInCompound: (element, full) =>
|
||||
`Bare element "${element}" in unscoped selector "${full}" at root level matches every "<${element}>" in the module. Anchor the selector with a class (e.g., ".container ${element}") or use :global() if intentional.`,
|
||||
});
|
||||
|
||||
const ELEMENT_PATTERN = /^[a-z][a-z0-9]*$/i;
|
||||
const EXCLUDED_ELEMENTS = new Set(['html', 'body', 'root']);
|
||||
|
||||
function isPartBareElement(part) {
|
||||
const trimmed = part.trim();
|
||||
if (!trimmed) {
|
||||
return false;
|
||||
}
|
||||
// Strip pseudo suffixes (`:hover`, `::before`) — element part is what's before
|
||||
const elementOnly = trimmed.split(':')[0];
|
||||
if (!elementOnly) {
|
||||
return false;
|
||||
}
|
||||
// Skip class/id/attribute parts
|
||||
if (/[.#[]/.test(elementOnly)) {
|
||||
return false;
|
||||
}
|
||||
return (
|
||||
ELEMENT_PATTERN.test(elementOnly) &&
|
||||
!EXCLUDED_ELEMENTS.has(elementOnly.toLowerCase())
|
||||
);
|
||||
}
|
||||
|
||||
function isBareElement(selector) {
|
||||
const trimmed = selector.trim();
|
||||
// Skip combined selectors
|
||||
if (/[,\s>+~]/.test(trimmed)) {
|
||||
return false;
|
||||
}
|
||||
// Skip pseudo-selectors
|
||||
if (trimmed.includes(':')) {
|
||||
return false;
|
||||
}
|
||||
// Skip class/id/attribute selectors
|
||||
if (/[.#[]/.test(trimmed)) {
|
||||
return false;
|
||||
}
|
||||
return (
|
||||
ELEMENT_PATTERN.test(trimmed) && !EXCLUDED_ELEMENTS.has(trimmed.toLowerCase())
|
||||
);
|
||||
}
|
||||
|
||||
// Split a compound selector on combinators (`>`, `+`, `~`, descendant space)
|
||||
// while keeping each part intact. Returns an array of selector parts.
|
||||
function splitOnCombinators(selector) {
|
||||
return selector
|
||||
.split(/\s*[>+~]\s*|\s+/)
|
||||
.map((p) => p.trim())
|
||||
.filter(Boolean);
|
||||
}
|
||||
|
||||
function isInsideGlobal(selector) {
|
||||
return /:global\s*\(/.test(selector);
|
||||
}
|
||||
|
||||
const KEYFRAME_ATRULES = new Set([
|
||||
'keyframes',
|
||||
'-webkit-keyframes',
|
||||
'-moz-keyframes',
|
||||
'-o-keyframes',
|
||||
]);
|
||||
|
||||
// Rule's effective parent is root if all ancestors above it are atrules
|
||||
// (e.g. `@media`, `@supports`). A bare `div` inside `@media { }` at top level
|
||||
// still matches every `<div>` in the module. Exclude `@keyframes` — its
|
||||
// `from`/`to`/`0%` children are not element selectors.
|
||||
function isEffectivelyTopLevel(node) {
|
||||
let parent = node.parent;
|
||||
while (parent && parent.type === 'atrule') {
|
||||
if (KEYFRAME_ATRULES.has(parent.name.toLowerCase())) {
|
||||
return false;
|
||||
}
|
||||
parent = parent.parent;
|
||||
}
|
||||
return Boolean(parent) && parent.type === 'root';
|
||||
}
|
||||
|
||||
const rule = (primaryOption) => {
|
||||
return (root, result) => {
|
||||
if (!primaryOption) {
|
||||
return;
|
||||
}
|
||||
|
||||
root.walkRules((ruleNode) => {
|
||||
if (!isEffectivelyTopLevel(ruleNode)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const selectors = ruleNode.selector.split(',').map((s) => s.trim());
|
||||
|
||||
for (const selector of selectors) {
|
||||
if (isInsideGlobal(selector)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isBareElement(selector)) {
|
||||
stylelint.utils.report({
|
||||
message: messages.unexpected(selector),
|
||||
node: ruleNode,
|
||||
result,
|
||||
ruleName,
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check combined selectors part-by-part. Only flag when the compound
|
||||
// has NO class/id anchor — `.container > div` is already scoped, but
|
||||
// `div + span` at root affects every matching descendant in the module.
|
||||
if (/[\s>+~]/.test(selector) && !/[.#]/.test(selector)) {
|
||||
const parts = splitOnCombinators(selector);
|
||||
for (const part of parts) {
|
||||
if (isPartBareElement(part)) {
|
||||
stylelint.utils.report({
|
||||
message: messages.unexpectedInCompound(part.split(':')[0], selector),
|
||||
node: ruleNode,
|
||||
result,
|
||||
ruleName,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
rule.ruleName = ruleName;
|
||||
rule.messages = messages;
|
||||
rule.meta = {};
|
||||
|
||||
export { ruleName, rule };
|
||||
export default { ruleName, rule };
|
||||
97
frontend/stylelint-rules/css-modules/no-deep-nesting.js
Normal file
@@ -0,0 +1,97 @@
|
||||
/**
|
||||
* Stylelint rule: local/no-deep-nesting
|
||||
*
|
||||
* Prevents deep nesting in CSS modules (max 3 levels).
|
||||
* Deep nesting creates specificity wars and hard-to-override styles.
|
||||
*
|
||||
* BAD:
|
||||
* .container { .wrapper { .inner { .content { } } } } // 4 levels
|
||||
*
|
||||
* GOOD:
|
||||
* .container { }
|
||||
* .containerWrapper { }
|
||||
* .containerContent { }
|
||||
*
|
||||
* Allowed nesting (pseudo-classes/elements):
|
||||
* .button { &:hover { } &::before { } }
|
||||
*/
|
||||
import stylelint from 'stylelint';
|
||||
|
||||
const ruleName = 'local/no-deep-nesting';
|
||||
const DEFAULT_MAX_DEPTH = 3;
|
||||
|
||||
const messages = stylelint.utils.ruleMessages(ruleName, {
|
||||
tooDeep: (depth, max) =>
|
||||
`Nesting depth ${depth} exceeds maximum of ${max}. Flatten selectors for CSS modules.`,
|
||||
});
|
||||
|
||||
function isPseudoSelector(selector) {
|
||||
return /^&?:/.test(selector.trim());
|
||||
}
|
||||
|
||||
function isParentReference(selector) {
|
||||
return /^&[.#[]/.test(selector.trim());
|
||||
}
|
||||
|
||||
function countNestingDepth(rule, depth = 0) {
|
||||
const selector = rule.selector || '';
|
||||
|
||||
// Don't count pseudo-selectors or parent references toward depth
|
||||
if (isPseudoSelector(selector) || isParentReference(selector)) {
|
||||
// Still check children
|
||||
let maxChildDepth = depth;
|
||||
rule.walkRules?.((child) => {
|
||||
const childDepth = countNestingDepth(child, depth);
|
||||
maxChildDepth = Math.max(maxChildDepth, childDepth);
|
||||
});
|
||||
return maxChildDepth;
|
||||
}
|
||||
|
||||
const currentDepth = depth + 1;
|
||||
let maxDepth = currentDepth;
|
||||
|
||||
rule.walkRules?.((child) => {
|
||||
const childDepth = countNestingDepth(child, currentDepth);
|
||||
maxDepth = Math.max(maxDepth, childDepth);
|
||||
});
|
||||
|
||||
return maxDepth;
|
||||
}
|
||||
|
||||
const rule = (primaryOption, secondaryOptions) => {
|
||||
return (root, result) => {
|
||||
if (!primaryOption) {
|
||||
return;
|
||||
}
|
||||
|
||||
const maxDepth =
|
||||
secondaryOptions && Number.isInteger(secondaryOptions.maxDepth)
|
||||
? secondaryOptions.maxDepth
|
||||
: DEFAULT_MAX_DEPTH;
|
||||
|
||||
root.walkRules((ruleNode) => {
|
||||
// Only check top-level rules
|
||||
if (ruleNode.parent.type !== 'root' && ruleNode.parent.type !== 'atrule') {
|
||||
return;
|
||||
}
|
||||
|
||||
const depth = countNestingDepth(ruleNode);
|
||||
|
||||
if (depth > maxDepth) {
|
||||
stylelint.utils.report({
|
||||
message: messages.tooDeep(depth, maxDepth),
|
||||
node: ruleNode,
|
||||
result,
|
||||
ruleName,
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
rule.ruleName = ruleName;
|
||||
rule.messages = messages;
|
||||
rule.meta = {};
|
||||
|
||||
export { ruleName, rule };
|
||||
export default { ruleName, rule };
|
||||
55
frontend/stylelint-rules/css-modules/no-id-selectors.js
Normal file
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* Stylelint rule: local/no-id-selectors
|
||||
*
|
||||
* Prevents ID selectors in CSS modules.
|
||||
* IDs create high specificity, can't be reused, and defeat CSS modules scoping purpose.
|
||||
*
|
||||
* BAD:
|
||||
* #myComponent { }
|
||||
* .container #header { }
|
||||
*
|
||||
* GOOD:
|
||||
* .myComponent { }
|
||||
* .containerHeader { }
|
||||
*/
|
||||
import stylelint from 'stylelint';
|
||||
|
||||
const ruleName = 'local/no-id-selectors';
|
||||
|
||||
const messages = stylelint.utils.ruleMessages(ruleName, {
|
||||
unexpected: (selector) =>
|
||||
`ID selector "${selector}" not allowed in CSS modules. Use class selector instead.`,
|
||||
});
|
||||
|
||||
const ID_PATTERN = /#[a-zA-Z_][a-zA-Z0-9_-]*/g;
|
||||
|
||||
const rule = (primaryOption) => {
|
||||
return (root, result) => {
|
||||
if (!primaryOption) {
|
||||
return;
|
||||
}
|
||||
|
||||
root.walkRules((ruleNode) => {
|
||||
const selector = ruleNode.selector;
|
||||
const matches = selector.match(ID_PATTERN);
|
||||
|
||||
if (matches) {
|
||||
for (const match of matches) {
|
||||
stylelint.utils.report({
|
||||
message: messages.unexpected(match),
|
||||
node: ruleNode,
|
||||
result,
|
||||
ruleName,
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
rule.ruleName = ruleName;
|
||||
rule.messages = messages;
|
||||
rule.meta = {};
|
||||
|
||||
export { ruleName, rule };
|
||||
export default { ruleName, rule };
|
||||
168
frontend/stylelint-rules/css-modules/prefer-css-variables.js
Normal file
@@ -0,0 +1,168 @@
|
||||
/**
|
||||
* Stylelint rule: local/prefer-css-variables
|
||||
*
|
||||
* Warns on hardcoded colors in CSS modules.
|
||||
* Use CSS variables for consistent theming.
|
||||
*
|
||||
* BAD:
|
||||
* color: #ff0000;
|
||||
* background: rgb(255, 0, 0);
|
||||
* border: 1px solid blue;
|
||||
*
|
||||
* GOOD:
|
||||
* color: var(--l1-foreground);
|
||||
* background: var(--primary-background);
|
||||
* border: 1px solid var(--l2-border);
|
||||
*
|
||||
* ALLOWED:
|
||||
* transparent, inherit, currentColor, none
|
||||
* Colors inside var() fallbacks
|
||||
*/
|
||||
import stylelint from 'stylelint';
|
||||
|
||||
const ruleName = 'local/prefer-css-variables';
|
||||
|
||||
const messages = stylelint.utils.ruleMessages(ruleName, {
|
||||
hardcodedColor: (value, property) =>
|
||||
`Hardcoded color "${value}" in "${property}". Use a semantic CSS variable instead (e.g., var(--l1-foreground), var(--primary-background)). See docs/css-modules-guide.md.`,
|
||||
});
|
||||
|
||||
const COLOR_PROPERTIES = new Set([
|
||||
'color',
|
||||
'background',
|
||||
'background-color',
|
||||
'background-image',
|
||||
'border',
|
||||
'border-color',
|
||||
'border-top',
|
||||
'border-right',
|
||||
'border-bottom',
|
||||
'border-left',
|
||||
'border-top-color',
|
||||
'border-right-color',
|
||||
'border-bottom-color',
|
||||
'border-left-color',
|
||||
'border-image',
|
||||
'border-image-source',
|
||||
'outline',
|
||||
'outline-color',
|
||||
'box-shadow',
|
||||
'text-shadow',
|
||||
'fill',
|
||||
'stroke',
|
||||
'caret-color',
|
||||
'text-decoration-color',
|
||||
'column-rule-color',
|
||||
'mask',
|
||||
'mask-image',
|
||||
]);
|
||||
|
||||
const ALLOWED_VALUES = new Set([
|
||||
'transparent',
|
||||
'inherit',
|
||||
'initial',
|
||||
'unset',
|
||||
'currentcolor',
|
||||
'none',
|
||||
'auto',
|
||||
]);
|
||||
|
||||
const HEX_PATTERN = /#[0-9a-fA-F]{3,8}\b/;
|
||||
const RGB_PATTERN = /rgba?\s*\([^)]+\)/i;
|
||||
const HSL_PATTERN = /hsla?\s*\([^)]+\)/i;
|
||||
const NAMED_COLOR_PATTERN =
|
||||
/\b(red|blue|green|yellow|orange|purple|pink|black|white|gray|grey|cyan|magenta|brown|navy|teal|olive|maroon|lime|aqua|fuchsia|silver)\b/i;
|
||||
|
||||
// Strip balanced `fn(...)` sections (e.g. `var(...)`, `url(...)`) from value.
|
||||
// Handles nested parens by counting depth.
|
||||
function stripBalancedFn(value, fnName) {
|
||||
const needle = `${fnName}(`;
|
||||
let out = '';
|
||||
let i = 0;
|
||||
while (i < value.length) {
|
||||
if (value.startsWith(needle, i)) {
|
||||
let depth = 1;
|
||||
i += needle.length;
|
||||
while (i < value.length && depth > 0) {
|
||||
const ch = value[i];
|
||||
if (ch === '(') {
|
||||
depth++;
|
||||
} else if (ch === ')') {
|
||||
depth--;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
} else {
|
||||
out += value[i];
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
function containsHardcodedColor(value) {
|
||||
// Strip url(...) first — paths/fragments may contain hex-like or color-named substrings
|
||||
let scanned = value.includes('url(') ? stripBalancedFn(value, 'url') : value;
|
||||
|
||||
// Strip var(...) — color tokens inside var fallbacks are allowed
|
||||
if (scanned.includes('var(')) {
|
||||
scanned = stripBalancedFn(scanned, 'var');
|
||||
if (!scanned.trim()) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
const lower = scanned.toLowerCase();
|
||||
if (ALLOWED_VALUES.has(lower)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (HEX_PATTERN.test(scanned)) {
|
||||
return scanned.match(HEX_PATTERN)[0];
|
||||
}
|
||||
if (RGB_PATTERN.test(scanned)) {
|
||||
return scanned.match(RGB_PATTERN)[0];
|
||||
}
|
||||
if (HSL_PATTERN.test(scanned)) {
|
||||
return scanned.match(HSL_PATTERN)[0];
|
||||
}
|
||||
if (NAMED_COLOR_PATTERN.test(scanned)) {
|
||||
return scanned.match(NAMED_COLOR_PATTERN)[0];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
const rule = (primaryOption) => {
|
||||
return (root, result) => {
|
||||
if (!primaryOption) {
|
||||
return;
|
||||
}
|
||||
|
||||
root.walkDecls((decl) => {
|
||||
const prop = decl.prop.toLowerCase();
|
||||
|
||||
if (!COLOR_PROPERTIES.has(prop)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const hardcodedColor = containsHardcodedColor(decl.value);
|
||||
|
||||
if (hardcodedColor) {
|
||||
stylelint.utils.report({
|
||||
message: messages.hardcodedColor(hardcodedColor, decl.prop),
|
||||
node: decl,
|
||||
result,
|
||||
ruleName,
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
rule.ruleName = ruleName;
|
||||
rule.messages = messages;
|
||||
rule.meta = {};
|
||||
|
||||
export { ruleName, rule };
|
||||
export default { ruleName, rule };
|
||||
@@ -68,6 +68,23 @@ func (provider *provider) addDashboardRoutes(router *mux.Router) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := router.Handle("/api/v2/dashboards/{id}/clone", handler.New(provider.authzMiddleware.EditAccess(provider.dashboardHandler.CloneV2), handler.OpenAPIDef{
|
||||
ID: "CloneDashboardV2",
|
||||
Tags: []string{"dashboard"},
|
||||
Summary: "Clone dashboard (v2)",
|
||||
Description: "This endpoint clones an existing v2-shape dashboard. User and integration dashboards can be cloned; system dashboards are rejected. The clone keeps the source's display name, panels, and tags, but gets a freshly generated unique internal name and is always created as an unlocked user dashboard owned by the caller.",
|
||||
Request: nil,
|
||||
RequestContentType: "",
|
||||
Response: new(dashboardtypes.GettableDashboardV2),
|
||||
ResponseContentType: "application/json",
|
||||
SuccessStatusCode: http.StatusCreated,
|
||||
ErrorStatusCodes: []int{http.StatusBadRequest, http.StatusNotFound},
|
||||
Deprecated: false,
|
||||
SecuritySchemes: newSecuritySchemes(types.RoleEditor),
|
||||
})).Methods(http.MethodPost).GetError(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := router.Handle("/api/v2/dashboards/{id}", handler.New(provider.authzMiddleware.ViewAccess(provider.dashboardHandler.GetV2), handler.OpenAPIDef{
|
||||
ID: "GetDashboardV2",
|
||||
Tags: []string{"dashboard"},
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
<svg id="ba7e3c83-4ea6-40d5-820f-746ccedb8156" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18"><defs><linearGradient id="e74ddf23-fe74-4f89-9a49-c7f2e22be284" x1="3.707" y1="5.123" x2="3.707" y2="2.061" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#0078d4"/><stop offset="1" stop-color="#5ea0ef"/></linearGradient><linearGradient id="bcce3b94-6b83-44c5-9bf7-a89d666f3d1e" x1="12.741" y1="10.558" x2="12.741" y2="5.161" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#0078d4"/><stop offset="1" stop-color="#5ea0ef"/></linearGradient><linearGradient id="f9b0803f-41e5-4165-9230-e220427ec475" x1="3.707" y1="13.723" x2="3.707" y2="10.378" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#0078d4"/><stop offset="1" stop-color="#5ea0ef"/></linearGradient></defs><g><g><rect x="7.923" y="1.922" width="0.98" height="6.183" transform="translate(0.013 10.048) rotate(-61.725)" fill="#003067"/><path d="M7.081,4.2V1.5H.33v2.7h0v0c0,.716,1.511,1.3,3.376,1.3s3.376-.58,3.376-1.3Z" fill="url(#e74ddf23-fe74-4f89-9a49-c7f2e22be284)"/><ellipse cx="3.707" cy="1.546" rx="3.376" ry="1.296" fill="#83b9f9"/><path d="M16.115,8.616v-2.7H9.365v2.7h0v0c0,.716,1.511,1.3,3.376,1.3s3.376-.58,3.376-1.3Z" fill="url(#bcce3b94-6b83-44c5-9bf7-a89d666f3d1e)"/><ellipse cx="12.741" cy="5.96" rx="3.376" ry="1.296" fill="#83b9f9"/><rect x="3.22" y="4.168" width="0.98" height="7.962" fill="#003067"/><circle cx="3.75" cy="3.337" r="1.157" fill="#c3f1ff"/><path d="M7.081,12.824v-2.7H.33v2.7h0v0c0,.716,1.511,1.3,3.376,1.3s3.376-.58,3.376-1.3Z" fill="url(#f9b0803f-41e5-4165-9230-e220427ec475)"/><ellipse cx="3.707" cy="10.167" rx="3.376" ry="1.296" fill="#83b9f9"/><rect x="3.708" y="9.164" width="9.741" height="0.98" transform="translate(-3.376 4.767) rotate(-26.14)" fill="#003067"/><circle cx="3.701" cy="11.939" r="1.157" fill="#c3f1ff"/><circle cx="12.743" cy="7.548" r="1.157" fill="#c3f1ff"/></g><g><path d="M17.166,15.5h0a.255.255,0,0,0-.1-.185A17,17,0,0,0,15.563,14a3.563,3.563,0,0,0-2.638-.706,5.515,5.515,0,0,0-3.339,2.066.224.224,0,0,0-.058.14h0v0h0a.26.26,0,0,0,.1.186,17.319,17.319,0,0,0,1.507,1.315,3.568,3.568,0,0,0,2.637.706,5.517,5.517,0,0,0,3.339-2.066.229.229,0,0,0,.059-.141h0Z" fill="#003067"/><circle cx="13.381" cy="15.501" r="1.846" fill="#c3f1ff"/><path d="M13.389,14.478a.875.875,0,0,0-.144.029.537.537,0,0,1,.1.292.559.559,0,0,1-.559.558.548.548,0,0,1-.368-.145.985.985,0,0,0-.062.3,1.038,1.038,0,1,0,1.038-1.037Z" fill="#003067"/><path d="M17.529,13.472A6.582,6.582,0,0,0,15.6,12.241l.437-.776a.458.458,0,0,0,.044-.34.441.441,0,0,0-.806-.106l-.535.952a5.762,5.762,0,0,0-.914-.143v-.975a.442.442,0,0,0-.883,0v.974a5.879,5.879,0,0,0-.934.144l-.536-.952a.442.442,0,0,0-.6-.158.45.45,0,0,0-.159.6q.219.387.437.776a6.582,6.582,0,0,0-1.931,1.231c-.422.382.2,1,.624.624a5.183,5.183,0,0,1,7.067,0C17.326,14.476,17.951,13.854,17.529,13.472Z" fill="#003067"/></g></g><rect x="-4.934" y="-3.691" width="29.331" height="34.261" fill="none" stroke="#b31b1b" stroke-miterlimit="10"/></svg>
|
||||
|
After Width: | Height: | Size: 3.0 KiB |
@@ -0,0 +1,7 @@
|
||||
### Monitor Azure Managed Instance for Apache Cassandra with SigNoz
|
||||
|
||||
Collect key Azure Managed Instance for Apache Cassandra metrics and view them with an out of the box dashboard.
|
||||
|
||||
This integration collects platform metrics for the `Microsoft.DocumentDB/cassandraClusters` resource type.
|
||||
|
||||
Note: This integration is for Azure Managed Instance for Apache Cassandra. Azure Cosmos DB for Apache Cassandra (the API offering) exposes a different set of metrics and is not covered here.
|
||||
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18"><defs><radialGradient id="a" cx="-105.006" cy="-10.409" r="5.954" gradientTransform="matrix(1.036 0 0 1.027 117.739 19.644)" gradientUnits="userSpaceOnUse"><stop offset=".183" stop-color="#5ea0ef"/><stop offset="1" stop-color="#0078d4"/></radialGradient><clipPath id="b"><path d="M14.969 7.53a6.137 6.137 0 11-7.395-4.543 6.137 6.137 0 017.395 4.543z" fill="none"/></clipPath></defs><path d="M2.954 5.266a.175.175 0 01-.176-.176A2.012 2.012 0 00.769 3.081a.176.176 0 01-.176-.175.176.176 0 01.176-.176A2.012 2.012 0 002.778.72a.175.175 0 01.176-.176.175.175 0 01.176.176 2.012 2.012 0 002.009 2.009.175.175 0 01.176.176.175.175 0 01-.176.176A2.011 2.011 0 003.13 5.09a.177.177 0 01-.176.176zM15.611 17.456a.141.141 0 01-.141-.141 1.609 1.609 0 00-1.607-1.607.141.141 0 01-.141-.14.141.141 0 01.141-.141 1.608 1.608 0 001.607-1.607.141.141 0 01.141-.141.141.141 0 01.141.141 1.608 1.608 0 001.607 1.607.141.141 0 110 .282 1.609 1.609 0 00-1.607 1.607.141.141 0 01-.141.14z" fill="#50e6ff"/><path d="M14.969 7.53a6.137 6.137 0 11-7.395-4.543 6.137 6.137 0 017.395 4.543z" fill="url(#a)"/><g clip-path="url(#b)" fill="#f2f2f2"><path d="M5.709 13.115a1.638 1.638 0 10.005-3.275 1.307 1.307 0 00.007-.14A1.651 1.651 0 004.06 8.064H2.832a6.251 6.251 0 001.595 5.051zM15.045 7.815c0-.015 0-.03-.007-.044a5.978 5.978 0 00-1.406-2.88 1.825 1.825 0 00-.289-.09 1.806 1.806 0 00-2.3 1.663 2 2 0 00-.2-.013 1.737 1.737 0 00-.581 3.374 1.451 1.451 0 00.541.1h2.03a13.453 13.453 0 002.212-2.11z"/></g><path d="M17.191 3.832c-.629-1.047-2.1-1.455-4.155-1.149a14.606 14.606 0 00-2.082.452 6.456 6.456 0 011.528.767c.241-.053.483-.116.715-.151a7.49 7.49 0 011.103-.089 2.188 2.188 0 011.959.725c.383.638.06 1.729-.886 3a16.723 16.723 0 01-4.749 4.051A16.758 16.758 0 014.8 13.7c-1.564.234-2.682 0-3.065-.636s-.06-1.73.886-2.995c.117-.157.146-.234.279-.392a6.252 6.252 0 01.026-1.63 11.552 11.552 0 00-1.17 1.372C.517 11.076.181 12.566.809 13.613a3.165 3.165 0 002.9 1.249 8.434 8.434 0 001.251-.1 17.855 17.855 0 006.219-2.4A17.808 17.808 0 0016.24 8.03c1.243-1.661 1.579-3.15.951-4.198z" fill="#50e6ff"/></svg>
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
@@ -0,0 +1,529 @@
|
||||
{
|
||||
"id": "cosmosdb",
|
||||
"title": "Cosmos DB",
|
||||
"icon": "file://icon.svg",
|
||||
"overview": "file://overview.md",
|
||||
"supportedSignals": {
|
||||
"metrics": true,
|
||||
"logs": true
|
||||
},
|
||||
"dataCollected": {
|
||||
"metrics": [
|
||||
{
|
||||
"name": "azure_totalrequests_count",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Number of requests made against the account."
|
||||
},
|
||||
{
|
||||
"name": "azure_totalrequestunits_total",
|
||||
"unit": "Count",
|
||||
"type": "Sum",
|
||||
"description": "Request Units (RUs) consumed."
|
||||
},
|
||||
{
|
||||
"name": "azure_totalrequestunits_average",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Request Units (RUs) consumed."
|
||||
},
|
||||
{
|
||||
"name": "azure_totalrequestunits_maximum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Request Units (RUs) consumed."
|
||||
},
|
||||
{
|
||||
"name": "azure_normalizedruconsumption_maximum",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Maximum RU consumption percentage per minute."
|
||||
},
|
||||
{
|
||||
"name": "azure_normalizedruconsumption_average",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Maximum RU consumption percentage per minute."
|
||||
},
|
||||
{
|
||||
"name": "azure_metadatarequests_count",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Count of metadata requests (enumerating databases/collections and their configurations)."
|
||||
},
|
||||
{
|
||||
"name": "azure_datausage_total",
|
||||
"unit": "Bytes",
|
||||
"type": "Sum",
|
||||
"description": "Total data usage, reported at 5-minute granularity."
|
||||
},
|
||||
{
|
||||
"name": "azure_datausage_average",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Total data usage, reported at 5-minute granularity."
|
||||
},
|
||||
{
|
||||
"name": "azure_datausage_maximum",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Total data usage, reported at 5-minute granularity."
|
||||
},
|
||||
{
|
||||
"name": "azure_datausage_minimum",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Total data usage, reported at 5-minute granularity."
|
||||
},
|
||||
{
|
||||
"name": "azure_indexusage_total",
|
||||
"unit": "Bytes",
|
||||
"type": "Sum",
|
||||
"description": "Total index usage, reported at 5-minute granularity."
|
||||
},
|
||||
{
|
||||
"name": "azure_indexusage_average",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Total index usage, reported at 5-minute granularity."
|
||||
},
|
||||
{
|
||||
"name": "azure_indexusage_maximum",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Total index usage, reported at 5-minute granularity."
|
||||
},
|
||||
{
|
||||
"name": "azure_indexusage_minimum",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Total index usage, reported at 5-minute granularity."
|
||||
},
|
||||
{
|
||||
"name": "azure_documentcountv2_total",
|
||||
"unit": "Count",
|
||||
"type": "Sum",
|
||||
"description": "Total document count."
|
||||
},
|
||||
{
|
||||
"name": "azure_documentcountv2_average",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Total document count."
|
||||
},
|
||||
{
|
||||
"name": "azure_documentquota_total",
|
||||
"unit": "Bytes",
|
||||
"type": "Sum",
|
||||
"description": "Total storage quota, reported at 5-minute granularity."
|
||||
},
|
||||
{
|
||||
"name": "azure_documentquota_average",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Total storage quota, reported at 5-minute granularity."
|
||||
},
|
||||
{
|
||||
"name": "azure_provisionedthroughput_maximum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Provisioned throughput (RU/s)."
|
||||
},
|
||||
{
|
||||
"name": "azure_autoscalemaxthroughput_maximum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Autoscale maximum throughput (RU/s)."
|
||||
},
|
||||
{
|
||||
"name": "azure_autoscaledru_maximum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Autoscaled RU consumption per region and per partition."
|
||||
},
|
||||
{
|
||||
"name": "azure_serversidelatencydirect_average",
|
||||
"unit": "MilliSeconds",
|
||||
"type": "Gauge",
|
||||
"description": "Server-side latency in Direct connection mode."
|
||||
},
|
||||
{
|
||||
"name": "azure_serversidelatencydirect_minimum",
|
||||
"unit": "MilliSeconds",
|
||||
"type": "Gauge",
|
||||
"description": "Server-side latency in Direct connection mode."
|
||||
},
|
||||
{
|
||||
"name": "azure_serversidelatencydirect_maximum",
|
||||
"unit": "MilliSeconds",
|
||||
"type": "Gauge",
|
||||
"description": "Server-side latency in Direct connection mode."
|
||||
},
|
||||
{
|
||||
"name": "azure_serversidelatencydirect_total",
|
||||
"unit": "MilliSeconds",
|
||||
"type": "Sum",
|
||||
"description": "Server-side latency in Direct connection mode."
|
||||
},
|
||||
{
|
||||
"name": "azure_serversidelatencygateway_average",
|
||||
"unit": "MilliSeconds",
|
||||
"type": "Gauge",
|
||||
"description": "Server-side latency in Gateway connection mode."
|
||||
},
|
||||
{
|
||||
"name": "azure_serversidelatencygateway_minimum",
|
||||
"unit": "MilliSeconds",
|
||||
"type": "Gauge",
|
||||
"description": "Server-side latency in Gateway connection mode."
|
||||
},
|
||||
{
|
||||
"name": "azure_serversidelatencygateway_maximum",
|
||||
"unit": "MilliSeconds",
|
||||
"type": "Gauge",
|
||||
"description": "Server-side latency in Gateway connection mode."
|
||||
},
|
||||
{
|
||||
"name": "azure_serversidelatencygateway_total",
|
||||
"unit": "MilliSeconds",
|
||||
"type": "Sum",
|
||||
"description": "Server-side latency in Gateway connection mode."
|
||||
},
|
||||
{
|
||||
"name": "azure_replicationlatency_minimum",
|
||||
"unit": "MilliSeconds",
|
||||
"type": "Gauge",
|
||||
"description": "P99 replication latency across source and target regions for a geo-enabled account."
|
||||
},
|
||||
{
|
||||
"name": "azure_replicationlatency_maximum",
|
||||
"unit": "MilliSeconds",
|
||||
"type": "Gauge",
|
||||
"description": "P99 replication latency across source and target regions for a geo-enabled account."
|
||||
},
|
||||
{
|
||||
"name": "azure_replicationlatency_average",
|
||||
"unit": "MilliSeconds",
|
||||
"type": "Gauge",
|
||||
"description": "P99 replication latency across source and target regions for a geo-enabled account."
|
||||
},
|
||||
{
|
||||
"name": "azure_serviceavailability_minimum",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Account requests availability at one-hour, day, or month granularity."
|
||||
},
|
||||
{
|
||||
"name": "azure_serviceavailability_average",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Account requests availability at one-hour, day, or month granularity."
|
||||
},
|
||||
{
|
||||
"name": "azure_serviceavailability_maximum",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Account requests availability at one-hour, day, or month granularity."
|
||||
},
|
||||
{
|
||||
"name": "azure_physicalpartitioncount_maximum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Physical partition count."
|
||||
},
|
||||
{
|
||||
"name": "azure_physicalpartitionsizeinfo_maximum",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Physical partition size in bytes."
|
||||
},
|
||||
{
|
||||
"name": "azure_physicalpartitionsizeinfo_average",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Physical partition size in bytes."
|
||||
},
|
||||
{
|
||||
"name": "azure_physicalpartitionthroughputinfo_maximum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Physical partition throughput (RU/s)."
|
||||
},
|
||||
{
|
||||
"name": "azure_cassandrarequests_count",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Number of Cassandra API requests made."
|
||||
},
|
||||
{
|
||||
"name": "azure_cassandrarequestcharges_total",
|
||||
"unit": "Count",
|
||||
"type": "Sum",
|
||||
"description": "Request Units consumed for Cassandra API requests."
|
||||
},
|
||||
{
|
||||
"name": "azure_cassandrarequestcharges_average",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Request Units consumed for Cassandra API requests."
|
||||
},
|
||||
{
|
||||
"name": "azure_cassandrarequestcharges_minimum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Request Units consumed for Cassandra API requests."
|
||||
},
|
||||
{
|
||||
"name": "azure_cassandrarequestcharges_maximum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Request Units consumed for Cassandra API requests."
|
||||
},
|
||||
{
|
||||
"name": "azure_cassandraconnectionclosures_average",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Number of Cassandra connections that were closed, reported at 1-minute granularity."
|
||||
},
|
||||
{
|
||||
"name": "azure_cassandraconnectionclosures_minimum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Number of Cassandra connections that were closed, reported at 1-minute granularity."
|
||||
},
|
||||
{
|
||||
"name": "azure_cassandraconnectionclosures_maximum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Number of Cassandra connections that were closed, reported at 1-minute granularity."
|
||||
},
|
||||
{
|
||||
"name": "azure_cassandraconnectionclosures_total",
|
||||
"unit": "Count",
|
||||
"type": "Sum",
|
||||
"description": "Number of Cassandra connections that were closed, reported at 1-minute granularity."
|
||||
},
|
||||
{
|
||||
"name": "azure_gremlinrequests_count",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Number of Gremlin API requests made."
|
||||
},
|
||||
{
|
||||
"name": "azure_gremlinrequestcharges_total",
|
||||
"unit": "Count",
|
||||
"type": "Sum",
|
||||
"description": "Request Units consumed for Gremlin API requests."
|
||||
},
|
||||
{
|
||||
"name": "azure_gremlinrequestcharges_average",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Request Units consumed for Gremlin API requests."
|
||||
},
|
||||
{
|
||||
"name": "azure_gremlinrequestcharges_minimum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Request Units consumed for Gremlin API requests."
|
||||
},
|
||||
{
|
||||
"name": "azure_gremlinrequestcharges_maximum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Request Units consumed for Gremlin API requests."
|
||||
},
|
||||
{
|
||||
"name": "azure_mongorequests_count",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Number of Mongo API requests made."
|
||||
},
|
||||
{
|
||||
"name": "azure_mongorequestcharge_total",
|
||||
"unit": "Count",
|
||||
"type": "Sum",
|
||||
"description": "Request Units consumed for Mongo API requests."
|
||||
},
|
||||
{
|
||||
"name": "azure_mongorequestcharge_average",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Request Units consumed for Mongo API requests."
|
||||
},
|
||||
{
|
||||
"name": "azure_mongorequestcharge_maximum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Request Units consumed for Mongo API requests."
|
||||
},
|
||||
{
|
||||
"name": "azure_dedicatedgatewayaveragecpuusage_average",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Average CPU usage across dedicated gateway instances."
|
||||
},
|
||||
{
|
||||
"name": "azure_dedicatedgatewaymaximumcpuusage_average",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Average maximum CPU usage across dedicated gateway instances."
|
||||
},
|
||||
{
|
||||
"name": "azure_dedicatedgatewaymaximumcpuusage_maximum",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Average maximum CPU usage across dedicated gateway instances."
|
||||
},
|
||||
{
|
||||
"name": "azure_dedicatedgatewaycpuusage_average",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "CPU usage across dedicated gateway instances."
|
||||
},
|
||||
{
|
||||
"name": "azure_dedicatedgatewaycpuusage_maximum",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "CPU usage across dedicated gateway instances."
|
||||
},
|
||||
{
|
||||
"name": "azure_dedicatedgatewaycpuusage_minimum",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "CPU usage across dedicated gateway instances."
|
||||
},
|
||||
{
|
||||
"name": "azure_dedicatedgatewayaveragememoryusage_average",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Average memory usage across dedicated gateway instances."
|
||||
},
|
||||
{
|
||||
"name": "azure_dedicatedgatewaymemoryusage_average",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Memory usage across dedicated gateway instances."
|
||||
},
|
||||
{
|
||||
"name": "azure_dedicatedgatewaymemoryusage_maximum",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Memory usage across dedicated gateway instances."
|
||||
},
|
||||
{
|
||||
"name": "azure_dedicatedgatewaymemoryusage_minimum",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Memory usage across dedicated gateway instances."
|
||||
},
|
||||
{
|
||||
"name": "azure_dedicatedgatewayrequests_count",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Requests at the dedicated gateway."
|
||||
},
|
||||
{
|
||||
"name": "azure_integratedcacheevictedentriessize_average",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Size of the entries evicted from the integrated cache."
|
||||
},
|
||||
{
|
||||
"name": "azure_integratedcacheitemexpirationcount_average",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Number of items evicted from the integrated cache due to TTL expiration."
|
||||
},
|
||||
{
|
||||
"name": "azure_integratedcacheitemhitrate_average",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Point reads that used the integrated cache divided by point reads routed through the dedicated gateway with eventual consistency."
|
||||
},
|
||||
{
|
||||
"name": "azure_integratedcachequeryexpirationcount_average",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Number of queries evicted from the integrated cache due to TTL expiration."
|
||||
},
|
||||
{
|
||||
"name": "azure_integratedcachequeryhitrate_average",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Queries that used the integrated cache divided by queries routed through the dedicated gateway with eventual consistency."
|
||||
},
|
||||
{
|
||||
"name": "azure_materializedviewcatchupgapinminutes_maximum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Maximum time difference (minutes) between data in the source container and data propagated to the materialized view."
|
||||
},
|
||||
{
|
||||
"name": "azure_materializedviewsbuilderaveragecpuusage_average",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Average CPU usage across materialized view builder instances."
|
||||
},
|
||||
{
|
||||
"name": "azure_materializedviewsbuildermaximumcpuusage_average",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Average maximum CPU usage across materialized view builder instances."
|
||||
},
|
||||
{
|
||||
"name": "azure_materializedviewsbuildermaximumcpuusage_maximum",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Average maximum CPU usage across materialized view builder instances."
|
||||
},
|
||||
{
|
||||
"name": "azure_materializedviewsbuilderaveragememoryusage_average",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Average memory usage across materialized view builder instances."
|
||||
},
|
||||
{
|
||||
"name": "azure_globalsecondaryindexcatchupgapinminutes_maximum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Maximum time difference (minutes) between data in the source container and data propagated to the global secondary index."
|
||||
},
|
||||
{
|
||||
"name": "azure_globalsecondaryindexpropagationlatencyinseconds_average",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Average time difference (seconds) between data in the source container and data propagated to the global secondary index."
|
||||
}
|
||||
],
|
||||
"logs": [
|
||||
{
|
||||
"name": "Resource ID",
|
||||
"path": "resources.azure.resource.id",
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"telemetryCollectionStrategy": {
|
||||
"azure": {
|
||||
"resourceProvider": "Microsoft.DocumentDB",
|
||||
"resourceType": "databaseAccounts",
|
||||
"metrics": {},
|
||||
"logs": {
|
||||
"categoryGroups": [
|
||||
"allLogs"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"assets": {
|
||||
"dashboards": [
|
||||
{
|
||||
"id": "overview",
|
||||
"title": "Azure Cosmos DB Overview",
|
||||
"description": "Overview of Azure Cosmos DB metrics",
|
||||
"definition": "file://assets/dashboards/overview.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
### Monitor Azure Cosmos DB with SigNoz
|
||||
|
||||
Collect key Azure Cosmos DB metrics and view them with an out of the box dashboard.
|
||||
|
||||
This integration collects platform metrics for the `Microsoft.DocumentDB/databaseAccounts` resource type — the Request Unit (RU) based Azure Cosmos DB account. A single account resource type is used across all Cosmos DB APIs (NoSQL, Cassandra, Gremlin, Table, and MongoDB for RU), so per-API request metrics are only reported for the API your account uses.
|
||||
|
||||
Note: This integration is for the RU-based Cosmos DB account (`Microsoft.DocumentDB/databaseAccounts`).
|
||||
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 61 81" fill="#fff" fill-rule="evenodd" stroke="#000" stroke-linecap="round" stroke-linejoin="round"><use xlink:href="#A" x=".5" y=".5"/><symbol id="A" overflow="visible"><g stroke="none"><path d="M0 10.88v58.08c0 6.08 13.333 10.88 30 10.88V10.88H0z" fill="#3999c6"/><path d="M29.524 80H30c16.508 0 30-4.96 30-10.88V10.88H29.524V80z" fill="#59b4d9"/><path d="M60 10.88c0 6.08-13.333 10.88-30 10.88S0 16.96 0 10.88C0 4.96 13.492 0 30 0s30 4.96 30 10.88"/><path d="M53.81 10.24c0 4-10.635 7.2-23.81 7.2s-23.809-3.2-23.809-7.2 10.635-7.2 23.81-7.2 23.81 3.2 23.81 7.2" fill="#7fba00"/><path d="M48.889 14.72c3.175-1.28 4.921-2.72 4.921-4.48 0-4-10.635-7.2-23.81-7.2s-23.809 3.2-23.809 7.2c0 1.6 1.905 3.2 4.921 4.48 4.286-1.76 11.111-2.88 18.889-2.88 7.619 0 14.444 1.12 18.889 2.88" fill="#b8d432"/><path d="M21.429 66.88c-2.381 0-4.286-.32-5.555-.8-1.429-.48-2.381-1.28-3.016-2.24-.635-1.12-.952-2.72-.952-4.8v-3.52c0-2.24-.952-3.52-2.857-3.52v-4.32c1.905 0 2.857-1.12 2.857-3.52v-3.2c0-2.24.317-4 .952-4.96.635-1.12 1.587-1.76 2.857-2.4 1.429-.48 3.175-.8 5.556-.8v4.32c-1.111 0-1.746.16-2.381.64-.476.48-.794 1.28-.794 2.4v2.72c0 1.76-.159 3.2-.635 4.32s-1.27 1.92-2.381 2.4h0c1.111.48 1.905 1.28 2.381 2.56.476 1.12.794 2.72.794 4.48v2.4c0 1.12.159 1.92.635 2.4s1.27.8 2.381.8v4.64zM48.413 52c-1.905 0-2.857 1.12-2.857 3.52v3.2c0 2.24-.318 4-.952 4.96-.635 1.12-1.587 1.76-2.857 2.4-1.428.48-3.175.8-5.556.8v-4.32c1.111 0 1.905-.16 2.381-.64s.794-1.28.794-2.4V56.8c0-1.76.159-3.2.635-4.32a4.39 4.39 0 0 1 2.381-2.4h0c-1.111-.48-1.905-1.44-2.381-2.56s-.794-2.72-.794-4.48v-2.4c0-1.12-.159-1.92-.635-2.4s-1.27-.8-2.381-.8v-4.32c2.381 0 4.286.32 5.556.8 1.428.48 2.381 1.28 3.016 2.24.635 1.12.953 2.72.953 4.8v3.52c0 2.24.952 3.52 2.857 3.52v4z"/></g></symbol></svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
@@ -0,0 +1,247 @@
|
||||
{
|
||||
"id": "mongodb",
|
||||
"title": "MongoDB (DocumentDB)",
|
||||
"icon": "file://icon.svg",
|
||||
"overview": "file://overview.md",
|
||||
"supportedSignals": {
|
||||
"metrics": true,
|
||||
"logs": true
|
||||
},
|
||||
"dataCollected": {
|
||||
"metrics": [
|
||||
{
|
||||
"name": "azure_cpupercent_average",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Percent CPU utilization on the node."
|
||||
},
|
||||
{
|
||||
"name": "azure_cpupercent_maximum",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Percent CPU utilization on the node."
|
||||
},
|
||||
{
|
||||
"name": "azure_cpupercent_minimum",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Percent CPU utilization on the node."
|
||||
},
|
||||
{
|
||||
"name": "azure_memorypercent_average",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Percent memory utilization on the node."
|
||||
},
|
||||
{
|
||||
"name": "azure_memorypercent_maximum",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Percent memory utilization on the node."
|
||||
},
|
||||
{
|
||||
"name": "azure_memorypercent_minimum",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Percent memory utilization on the node."
|
||||
},
|
||||
{
|
||||
"name": "azure_committedmemorypercent_average",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Percentage of the commit memory limit allocated by applications on the node."
|
||||
},
|
||||
{
|
||||
"name": "azure_committedmemorypercent_maximum",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Percentage of the commit memory limit allocated by applications on the node."
|
||||
},
|
||||
{
|
||||
"name": "azure_committedmemorypercent_minimum",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Percentage of the commit memory limit allocated by applications on the node."
|
||||
},
|
||||
{
|
||||
"name": "azure_storagepercent_average",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Percent of available storage used on the node."
|
||||
},
|
||||
{
|
||||
"name": "azure_storagepercent_maximum",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Percent of available storage used on the node."
|
||||
},
|
||||
{
|
||||
"name": "azure_storagepercent_minimum",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Percent of available storage used on the node."
|
||||
},
|
||||
{
|
||||
"name": "azure_storageused_average",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Quantity of available storage used on the node."
|
||||
},
|
||||
{
|
||||
"name": "azure_storageused_maximum",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Quantity of available storage used on the node."
|
||||
},
|
||||
{
|
||||
"name": "azure_storageused_minimum",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Quantity of available storage used on the node."
|
||||
},
|
||||
{
|
||||
"name": "azure_autoscaleutilizationpercent_average",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Percent autoscale utilization."
|
||||
},
|
||||
{
|
||||
"name": "azure_autoscaleutilizationpercent_maximum",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Percent autoscale utilization."
|
||||
},
|
||||
{
|
||||
"name": "azure_autoscaleutilizationpercent_minimum",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Percent autoscale utilization."
|
||||
},
|
||||
{
|
||||
"name": "azure_iops_average",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Disk IO operations per second on the node."
|
||||
},
|
||||
{
|
||||
"name": "azure_iops_maximum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Disk IO operations per second on the node."
|
||||
},
|
||||
{
|
||||
"name": "azure_iops_minimum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Disk IO operations per second on the node."
|
||||
},
|
||||
{
|
||||
"name": "azure_networkbytesegress_average",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Network bytes sent on the node."
|
||||
},
|
||||
{
|
||||
"name": "azure_networkbytesegress_maximum",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Network bytes sent on the node."
|
||||
},
|
||||
{
|
||||
"name": "azure_networkbytesegress_minimum",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Network bytes sent on the node."
|
||||
},
|
||||
{
|
||||
"name": "azure_networkbytesegress_total",
|
||||
"unit": "Bytes",
|
||||
"type": "Sum",
|
||||
"description": "Network bytes sent on the node."
|
||||
},
|
||||
{
|
||||
"name": "azure_networkbytesingress_average",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Network bytes received on the node."
|
||||
},
|
||||
{
|
||||
"name": "azure_networkbytesingress_maximum",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Network bytes received on the node."
|
||||
},
|
||||
{
|
||||
"name": "azure_networkbytesingress_minimum",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Network bytes received on the node."
|
||||
},
|
||||
{
|
||||
"name": "azure_networkbytesingress_total",
|
||||
"unit": "Bytes",
|
||||
"type": "Sum",
|
||||
"description": "Network bytes received on the node."
|
||||
},
|
||||
{
|
||||
"name": "azure_mongorequestdurationms_average",
|
||||
"unit": "Milliseconds",
|
||||
"type": "Gauge",
|
||||
"description": "End-to-end duration in milliseconds of client MongoDB requests handled by the cluster."
|
||||
},
|
||||
{
|
||||
"name": "azure_mongorequestdurationms_maximum",
|
||||
"unit": "Milliseconds",
|
||||
"type": "Gauge",
|
||||
"description": "End-to-end duration in milliseconds of client MongoDB requests handled by the cluster."
|
||||
},
|
||||
{
|
||||
"name": "azure_mongorequestdurationms_minimum",
|
||||
"unit": "Milliseconds",
|
||||
"type": "Gauge",
|
||||
"description": "End-to-end duration in milliseconds of client MongoDB requests handled by the cluster."
|
||||
},
|
||||
{
|
||||
"name": "azure_mongorequestdurationms_total",
|
||||
"unit": "Milliseconds",
|
||||
"type": "Sum",
|
||||
"description": "End-to-end duration in milliseconds of client MongoDB requests handled by the cluster."
|
||||
},
|
||||
{
|
||||
"name": "azure_mongorequestdurationms_count",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Number of client MongoDB requests handled by the cluster."
|
||||
}
|
||||
],
|
||||
"logs": [
|
||||
{
|
||||
"name": "Resource ID",
|
||||
"path": "resources.azure.resource.id",
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"telemetryCollectionStrategy": {
|
||||
"azure": {
|
||||
"resourceProvider": "Microsoft.DocumentDB",
|
||||
"resourceType": "mongoClusters",
|
||||
"metrics": {},
|
||||
"logs": {
|
||||
"categoryGroups": [
|
||||
"allLogs"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"assets": {
|
||||
"dashboards": [
|
||||
{
|
||||
"id": "overview",
|
||||
"title": "Azure MongoDB (DocumentDB) Overview",
|
||||
"description": "Overview of Azure MongoDB (DocumentDB) metrics",
|
||||
"definition": "file://assets/dashboards/overview.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
### Monitor Azure MongoDB with SigNoz
|
||||
|
||||
Collect key Azure MongoDB (DocumentDB) cluster metrics and view them with an out of the box dashboard.
|
||||
|
||||
This integration collects platform metrics for the `Microsoft.DocumentDB/mongoClusters` resource type — the vCore-based Azure DocumentDB offering with MongoDB compatibility.
|
||||
@@ -0,0 +1 @@
|
||||
<svg id="e05c9575-4c38-4bcd-90eb-276caf26e3d0" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18"><defs><linearGradient id="e291aba6-8038-4db1-a04d-c7be74f5a3e6" x1="2.59" y1="10.16" x2="15.41" y2="10.16" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#005ba1"/><stop offset="0.07" stop-color="#0060a9"/><stop offset="0.36" stop-color="#0071c8"/><stop offset="0.52" stop-color="#0078d4"/><stop offset="0.64" stop-color="#0074cd"/><stop offset="0.82" stop-color="#006abb"/><stop offset="1" stop-color="#005ba1"/></linearGradient></defs><title>Icon-databases-122</title><path d="M9,5.14c-3.54,0-6.41-1-6.41-2.32V15.18c0,1.27,2.82,2.3,6.32,2.32H9c3.54,0,6.41-1,6.41-2.32V2.82C15.41,4.11,12.54,5.14,9,5.14Z" fill="url(#e291aba6-8038-4db1-a04d-c7be74f5a3e6)"/><path d="M15.41,2.82c0,1.29-2.87,2.32-6.41,2.32s-6.41-1-6.41-2.32S5.46.5,9,.5s6.41,1,6.41,2.32" fill="#e8e8e8"/><path d="M13.92,2.63c0,.82-2.21,1.48-4.92,1.48S4.08,3.45,4.08,2.63,6.29,1.16,9,1.16s4.92.66,4.92,1.47" fill="#50e6ff"/><path d="M9,3a11.55,11.55,0,0,0-3.89.57A11.42,11.42,0,0,0,9,4.11a11.15,11.15,0,0,0,3.89-.58A11.84,11.84,0,0,0,9,3Z" fill="#198ab3"/><path d="M12.64,9v1.63h-1a.39.39,0,0,1-.29-.14V9H10v1.78a.92.92,0,0,0,1,.89h1.49l.26-.13s-.11.41-.26.43H10.11v1h2.66A1.21,1.21,0,0,0,14,11.7V9Z" fill="#f2f2f2"/><path d="M9.53,9s0,0,0,0V8.51a.7.7,0,0,0-.48-.77,1.74,1.74,0,0,0-.5-.08.94.94,0,0,0-.91.58l-.78,1.9-1-1.9A.93.93,0,0,0,5,7.66a1.44,1.44,0,0,0-.51.09c-.35.11-.43.34-.43.73v3.31H5.23V9.56l.63,1.57a1.08,1.08,0,0,0,1,.66c.44,0,.62-.26.8-.66l.67-1.51v2.15H9.51V9h0Z" fill="#f2f2f2"/></svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
@@ -0,0 +1,787 @@
|
||||
{
|
||||
"id": "mysqlflexibleserver",
|
||||
"title": "MySQL - Flexible Server",
|
||||
"icon": "file://icon.svg",
|
||||
"overview": "file://overview.md",
|
||||
"supportedSignals": {
|
||||
"metrics": true,
|
||||
"logs": true
|
||||
},
|
||||
"dataCollected": {
|
||||
"metrics": [
|
||||
{
|
||||
"name": "azure_ha_io_status_maximum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Status for replication IO thread running (HA)."
|
||||
},
|
||||
{
|
||||
"name": "azure_ha_sql_status_maximum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Status for replication SQL thread running (HA)."
|
||||
},
|
||||
{
|
||||
"name": "azure_replica_io_running_maximum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Status for replication IO thread running (replica)."
|
||||
},
|
||||
{
|
||||
"name": "azure_replica_sql_running_maximum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Status for replication SQL thread running (replica)."
|
||||
},
|
||||
{
|
||||
"name": "azure_aborted_connections_total",
|
||||
"unit": "Count",
|
||||
"type": "Sum",
|
||||
"description": "Number of failed attempts to connect to the MySQL server."
|
||||
},
|
||||
{
|
||||
"name": "azure_ha_replication_lag_average",
|
||||
"unit": "Seconds",
|
||||
"type": "Gauge",
|
||||
"description": "HA replication lag in seconds."
|
||||
},
|
||||
{
|
||||
"name": "azure_ha_replication_lag_maximum",
|
||||
"unit": "Seconds",
|
||||
"type": "Gauge",
|
||||
"description": "HA replication lag in seconds."
|
||||
},
|
||||
{
|
||||
"name": "azure_ha_replication_lag_minimum",
|
||||
"unit": "Seconds",
|
||||
"type": "Gauge",
|
||||
"description": "HA replication lag in seconds."
|
||||
},
|
||||
{
|
||||
"name": "azure_innodb_row_lock_time_average",
|
||||
"unit": "Milliseconds",
|
||||
"type": "Gauge",
|
||||
"description": "Total time spent acquiring row locks for InnoDB tables, in milliseconds."
|
||||
},
|
||||
{
|
||||
"name": "azure_innodb_row_lock_time_maximum",
|
||||
"unit": "Milliseconds",
|
||||
"type": "Gauge",
|
||||
"description": "Total time spent acquiring row locks for InnoDB tables, in milliseconds."
|
||||
},
|
||||
{
|
||||
"name": "azure_innodb_row_lock_time_minimum",
|
||||
"unit": "Milliseconds",
|
||||
"type": "Gauge",
|
||||
"description": "Total time spent acquiring row locks for InnoDB tables, in milliseconds."
|
||||
},
|
||||
{
|
||||
"name": "azure_innodb_row_lock_waits_total",
|
||||
"unit": "Count",
|
||||
"type": "Sum",
|
||||
"description": "Number of times operations on InnoDB tables had to wait for a row lock."
|
||||
},
|
||||
{
|
||||
"name": "azure_innodb_row_lock_waits_maximum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Number of times operations on InnoDB tables had to wait for a row lock."
|
||||
},
|
||||
{
|
||||
"name": "azure_innodb_row_lock_waits_minimum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Number of times operations on InnoDB tables had to wait for a row lock."
|
||||
},
|
||||
{
|
||||
"name": "azure_replication_lag_average",
|
||||
"unit": "Seconds",
|
||||
"type": "Gauge",
|
||||
"description": "Replication lag in seconds."
|
||||
},
|
||||
{
|
||||
"name": "azure_replication_lag_maximum",
|
||||
"unit": "Seconds",
|
||||
"type": "Gauge",
|
||||
"description": "Replication lag in seconds."
|
||||
},
|
||||
{
|
||||
"name": "azure_replication_lag_minimum",
|
||||
"unit": "Seconds",
|
||||
"type": "Gauge",
|
||||
"description": "Replication lag in seconds."
|
||||
},
|
||||
{
|
||||
"name": "azure_uptime_total",
|
||||
"unit": "Seconds",
|
||||
"type": "Sum",
|
||||
"description": "Number of seconds that the server has been up."
|
||||
},
|
||||
{
|
||||
"name": "azure_uptime_maximum",
|
||||
"unit": "Seconds",
|
||||
"type": "Gauge",
|
||||
"description": "Number of seconds that the server has been up."
|
||||
},
|
||||
{
|
||||
"name": "azure_backup_storage_used_average",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Backup storage used."
|
||||
},
|
||||
{
|
||||
"name": "azure_backup_storage_used_maximum",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Backup storage used."
|
||||
},
|
||||
{
|
||||
"name": "azure_backup_storage_used_minimum",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Backup storage used."
|
||||
},
|
||||
{
|
||||
"name": "azure_binlog_storage_used_average",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Storage used by binlog files."
|
||||
},
|
||||
{
|
||||
"name": "azure_binlog_storage_used_maximum",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Storage used by binlog files."
|
||||
},
|
||||
{
|
||||
"name": "azure_binlog_storage_used_minimum",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Storage used by binlog files."
|
||||
},
|
||||
{
|
||||
"name": "azure_cpu_credits_consumed_average",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "CPU credits consumed (Burstable SKU)."
|
||||
},
|
||||
{
|
||||
"name": "azure_cpu_credits_consumed_maximum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "CPU credits consumed (Burstable SKU)."
|
||||
},
|
||||
{
|
||||
"name": "azure_cpu_credits_consumed_minimum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "CPU credits consumed (Burstable SKU)."
|
||||
},
|
||||
{
|
||||
"name": "azure_cpu_credits_remaining_average",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "CPU credits remaining (Burstable SKU)."
|
||||
},
|
||||
{
|
||||
"name": "azure_cpu_credits_remaining_maximum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "CPU credits remaining (Burstable SKU)."
|
||||
},
|
||||
{
|
||||
"name": "azure_cpu_credits_remaining_minimum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "CPU credits remaining (Burstable SKU)."
|
||||
},
|
||||
{
|
||||
"name": "azure_cpu_percent_average",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Host CPU percent."
|
||||
},
|
||||
{
|
||||
"name": "azure_cpu_percent_maximum",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Host CPU percent."
|
||||
},
|
||||
{
|
||||
"name": "azure_cpu_percent_minimum",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Host CPU percent."
|
||||
},
|
||||
{
|
||||
"name": "azure_data_storage_used_average",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Storage used by data files."
|
||||
},
|
||||
{
|
||||
"name": "azure_data_storage_used_maximum",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Storage used by data files."
|
||||
},
|
||||
{
|
||||
"name": "azure_data_storage_used_minimum",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Storage used by data files."
|
||||
},
|
||||
{
|
||||
"name": "azure_ibdata1_storage_used_average",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Storage used by ibdata1 files."
|
||||
},
|
||||
{
|
||||
"name": "azure_ibdata1_storage_used_maximum",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Storage used by ibdata1 files."
|
||||
},
|
||||
{
|
||||
"name": "azure_ibdata1_storage_used_minimum",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Storage used by ibdata1 files."
|
||||
},
|
||||
{
|
||||
"name": "azure_innodb_buffer_pool_pages_data_total",
|
||||
"unit": "Count",
|
||||
"type": "Sum",
|
||||
"description": "Number of pages in the InnoDB buffer pool containing data."
|
||||
},
|
||||
{
|
||||
"name": "azure_innodb_buffer_pool_pages_data_maximum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Number of pages in the InnoDB buffer pool containing data."
|
||||
},
|
||||
{
|
||||
"name": "azure_innodb_buffer_pool_pages_data_minimum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Number of pages in the InnoDB buffer pool containing data."
|
||||
},
|
||||
{
|
||||
"name": "azure_innodb_buffer_pool_pages_dirty_total",
|
||||
"unit": "Count",
|
||||
"type": "Sum",
|
||||
"description": "Current number of dirty pages in the InnoDB buffer pool."
|
||||
},
|
||||
{
|
||||
"name": "azure_innodb_buffer_pool_pages_dirty_maximum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Current number of dirty pages in the InnoDB buffer pool."
|
||||
},
|
||||
{
|
||||
"name": "azure_innodb_buffer_pool_pages_dirty_minimum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Current number of dirty pages in the InnoDB buffer pool."
|
||||
},
|
||||
{
|
||||
"name": "azure_innodb_buffer_pool_pages_free_total",
|
||||
"unit": "Count",
|
||||
"type": "Sum",
|
||||
"description": "Number of free pages in the InnoDB buffer pool."
|
||||
},
|
||||
{
|
||||
"name": "azure_innodb_buffer_pool_pages_free_maximum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Number of free pages in the InnoDB buffer pool."
|
||||
},
|
||||
{
|
||||
"name": "azure_innodb_buffer_pool_pages_free_minimum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Number of free pages in the InnoDB buffer pool."
|
||||
},
|
||||
{
|
||||
"name": "azure_innodb_buffer_pool_read_requests_total",
|
||||
"unit": "Count",
|
||||
"type": "Sum",
|
||||
"description": "Number of logical read requests."
|
||||
},
|
||||
{
|
||||
"name": "azure_innodb_buffer_pool_read_requests_maximum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Number of logical read requests."
|
||||
},
|
||||
{
|
||||
"name": "azure_innodb_buffer_pool_read_requests_minimum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Number of logical read requests."
|
||||
},
|
||||
{
|
||||
"name": "azure_innodb_buffer_pool_reads_total",
|
||||
"unit": "Count",
|
||||
"type": "Sum",
|
||||
"description": "Number of logical reads that InnoDB could not satisfy from the buffer pool and had to read from disk."
|
||||
},
|
||||
{
|
||||
"name": "azure_innodb_buffer_pool_reads_maximum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Number of logical reads that InnoDB could not satisfy from the buffer pool and had to read from disk."
|
||||
},
|
||||
{
|
||||
"name": "azure_innodb_buffer_pool_reads_minimum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Number of logical reads that InnoDB could not satisfy from the buffer pool and had to read from disk."
|
||||
},
|
||||
{
|
||||
"name": "azure_io_consumption_percent_average",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Storage I/O consumption percent."
|
||||
},
|
||||
{
|
||||
"name": "azure_io_consumption_percent_maximum",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Storage I/O consumption percent."
|
||||
},
|
||||
{
|
||||
"name": "azure_io_consumption_percent_minimum",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Storage I/O consumption percent."
|
||||
},
|
||||
{
|
||||
"name": "azure_memory_percent_average",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Memory percent."
|
||||
},
|
||||
{
|
||||
"name": "azure_memory_percent_maximum",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Memory percent."
|
||||
},
|
||||
{
|
||||
"name": "azure_memory_percent_minimum",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Memory percent."
|
||||
},
|
||||
{
|
||||
"name": "azure_others_storage_used_average",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Storage used by other files."
|
||||
},
|
||||
{
|
||||
"name": "azure_others_storage_used_maximum",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Storage used by other files."
|
||||
},
|
||||
{
|
||||
"name": "azure_others_storage_used_minimum",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Storage used by other files."
|
||||
},
|
||||
{
|
||||
"name": "azure_serverlog_storage_limit_maximum",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Server log storage limit."
|
||||
},
|
||||
{
|
||||
"name": "azure_serverlog_storage_percent_average",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Server log storage percent."
|
||||
},
|
||||
{
|
||||
"name": "azure_serverlog_storage_percent_maximum",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Server log storage percent."
|
||||
},
|
||||
{
|
||||
"name": "azure_serverlog_storage_percent_minimum",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Server log storage percent."
|
||||
},
|
||||
{
|
||||
"name": "azure_serverlog_storage_usage_average",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Server log storage used."
|
||||
},
|
||||
{
|
||||
"name": "azure_serverlog_storage_usage_maximum",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Server log storage used."
|
||||
},
|
||||
{
|
||||
"name": "azure_serverlog_storage_usage_minimum",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Server log storage used."
|
||||
},
|
||||
{
|
||||
"name": "azure_sort_merge_passes_total",
|
||||
"unit": "Count",
|
||||
"type": "Sum",
|
||||
"description": "Number of merge passes the sort algorithm has had to do."
|
||||
},
|
||||
{
|
||||
"name": "azure_sort_merge_passes_maximum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Number of merge passes the sort algorithm has had to do."
|
||||
},
|
||||
{
|
||||
"name": "azure_sort_merge_passes_minimum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Number of merge passes the sort algorithm has had to do."
|
||||
},
|
||||
{
|
||||
"name": "azure_storage_limit_maximum",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Storage limit."
|
||||
},
|
||||
{
|
||||
"name": "azure_storage_percent_average",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Storage percent."
|
||||
},
|
||||
{
|
||||
"name": "azure_storage_percent_maximum",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Storage percent."
|
||||
},
|
||||
{
|
||||
"name": "azure_storage_percent_minimum",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Storage percent."
|
||||
},
|
||||
{
|
||||
"name": "azure_storage_used_average",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Storage used."
|
||||
},
|
||||
{
|
||||
"name": "azure_storage_used_maximum",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Storage used."
|
||||
},
|
||||
{
|
||||
"name": "azure_storage_used_minimum",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Storage used."
|
||||
},
|
||||
{
|
||||
"name": "azure_threads_running_total",
|
||||
"unit": "Count",
|
||||
"type": "Sum",
|
||||
"description": "Number of threads that are not sleeping."
|
||||
},
|
||||
{
|
||||
"name": "azure_threads_running_maximum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Number of threads that are not sleeping."
|
||||
},
|
||||
{
|
||||
"name": "azure_threads_running_minimum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Number of threads that are not sleeping."
|
||||
},
|
||||
{
|
||||
"name": "azure_active_connections_average",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Active connections."
|
||||
},
|
||||
{
|
||||
"name": "azure_active_connections_maximum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Active connections."
|
||||
},
|
||||
{
|
||||
"name": "azure_active_connections_minimum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Active connections."
|
||||
},
|
||||
{
|
||||
"name": "azure_active_transactions_total",
|
||||
"unit": "Count",
|
||||
"type": "Sum",
|
||||
"description": "Number of active transactions."
|
||||
},
|
||||
{
|
||||
"name": "azure_active_transactions_average",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Number of active transactions."
|
||||
},
|
||||
{
|
||||
"name": "azure_active_transactions_maximum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Number of active transactions."
|
||||
},
|
||||
{
|
||||
"name": "azure_active_transactions_minimum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Number of active transactions."
|
||||
},
|
||||
{
|
||||
"name": "azure_com_alter_table_total",
|
||||
"unit": "Count",
|
||||
"type": "Sum",
|
||||
"description": "Number of times ALTER TABLE statement has been executed."
|
||||
},
|
||||
{
|
||||
"name": "azure_com_create_db_total",
|
||||
"unit": "Count",
|
||||
"type": "Sum",
|
||||
"description": "Number of times CREATE DB statement has been executed."
|
||||
},
|
||||
{
|
||||
"name": "azure_com_create_table_total",
|
||||
"unit": "Count",
|
||||
"type": "Sum",
|
||||
"description": "Number of times CREATE TABLE statement has been executed."
|
||||
},
|
||||
{
|
||||
"name": "azure_com_delete_total",
|
||||
"unit": "Count",
|
||||
"type": "Sum",
|
||||
"description": "Number of times DELETE statement has been executed."
|
||||
},
|
||||
{
|
||||
"name": "azure_com_drop_db_total",
|
||||
"unit": "Count",
|
||||
"type": "Sum",
|
||||
"description": "Number of times DROP DB statement has been executed."
|
||||
},
|
||||
{
|
||||
"name": "azure_com_drop_table_total",
|
||||
"unit": "Count",
|
||||
"type": "Sum",
|
||||
"description": "Number of times DROP TABLE statement has been executed."
|
||||
},
|
||||
{
|
||||
"name": "azure_com_insert_total",
|
||||
"unit": "Count",
|
||||
"type": "Sum",
|
||||
"description": "Number of times INSERT statement has been executed."
|
||||
},
|
||||
{
|
||||
"name": "azure_com_select_total",
|
||||
"unit": "Count",
|
||||
"type": "Sum",
|
||||
"description": "Number of times SELECT statement has been executed."
|
||||
},
|
||||
{
|
||||
"name": "azure_com_update_total",
|
||||
"unit": "Count",
|
||||
"type": "Sum",
|
||||
"description": "Number of times UPDATE statement has been executed."
|
||||
},
|
||||
{
|
||||
"name": "azure_innodb_buffer_pool_pages_flushed_average",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Number of requests to flush pages from the InnoDB buffer pool."
|
||||
},
|
||||
{
|
||||
"name": "azure_innodb_buffer_pool_pages_flushed_maximum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Number of requests to flush pages from the InnoDB buffer pool."
|
||||
},
|
||||
{
|
||||
"name": "azure_innodb_buffer_pool_pages_flushed_minimum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Number of requests to flush pages from the InnoDB buffer pool."
|
||||
},
|
||||
{
|
||||
"name": "azure_innodb_data_writes_total",
|
||||
"unit": "Count",
|
||||
"type": "Sum",
|
||||
"description": "Total number of data writes."
|
||||
},
|
||||
{
|
||||
"name": "azure_innodb_data_writes_maximum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Total number of data writes."
|
||||
},
|
||||
{
|
||||
"name": "azure_innodb_data_writes_minimum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Total number of data writes."
|
||||
},
|
||||
{
|
||||
"name": "azure_lock_deadlocks_total",
|
||||
"unit": "Count",
|
||||
"type": "Sum",
|
||||
"description": "Number of deadlocks."
|
||||
},
|
||||
{
|
||||
"name": "azure_lock_deadlocks_average",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Number of deadlocks."
|
||||
},
|
||||
{
|
||||
"name": "azure_lock_deadlocks_maximum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Number of deadlocks."
|
||||
},
|
||||
{
|
||||
"name": "azure_lock_deadlocks_minimum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Number of deadlocks."
|
||||
},
|
||||
{
|
||||
"name": "azure_lock_timeouts_total",
|
||||
"unit": "Count",
|
||||
"type": "Sum",
|
||||
"description": "Number of lock timeouts."
|
||||
},
|
||||
{
|
||||
"name": "azure_lock_timeouts_average",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Number of lock timeouts."
|
||||
},
|
||||
{
|
||||
"name": "azure_lock_timeouts_maximum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Number of lock timeouts."
|
||||
},
|
||||
{
|
||||
"name": "azure_lock_timeouts_minimum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Number of lock timeouts."
|
||||
},
|
||||
{
|
||||
"name": "azure_network_bytes_egress_total",
|
||||
"unit": "Bytes",
|
||||
"type": "Sum",
|
||||
"description": "Host network egress in bytes."
|
||||
},
|
||||
{
|
||||
"name": "azure_network_bytes_ingress_total",
|
||||
"unit": "Bytes",
|
||||
"type": "Sum",
|
||||
"description": "Host network ingress in bytes."
|
||||
},
|
||||
{
|
||||
"name": "azure_queries_total",
|
||||
"unit": "Count",
|
||||
"type": "Sum",
|
||||
"description": "Number of queries executed."
|
||||
},
|
||||
{
|
||||
"name": "azure_slow_queries_total",
|
||||
"unit": "Count",
|
||||
"type": "Sum",
|
||||
"description": "Number of queries that have taken more than long_query_time seconds."
|
||||
},
|
||||
{
|
||||
"name": "azure_storage_io_count_total",
|
||||
"unit": "Count",
|
||||
"type": "Sum",
|
||||
"description": "Number of storage I/O operations consumed."
|
||||
},
|
||||
{
|
||||
"name": "azure_total_connections_total",
|
||||
"unit": "Count",
|
||||
"type": "Sum",
|
||||
"description": "Total connections."
|
||||
},
|
||||
{
|
||||
"name": "azure_trx_rseg_history_len_total",
|
||||
"unit": "Count",
|
||||
"type": "Sum",
|
||||
"description": "Length of the TRX_RSEG_HISTORY list."
|
||||
},
|
||||
{
|
||||
"name": "azure_trx_rseg_history_len_average",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Length of the TRX_RSEG_HISTORY list."
|
||||
},
|
||||
{
|
||||
"name": "azure_trx_rseg_history_len_maximum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Length of the TRX_RSEG_HISTORY list."
|
||||
},
|
||||
{
|
||||
"name": "azure_trx_rseg_history_len_minimum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Length of the TRX_RSEG_HISTORY list."
|
||||
}
|
||||
],
|
||||
"logs": [
|
||||
{
|
||||
"name": "Resource ID",
|
||||
"path": "resources.azure.resource.id",
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"telemetryCollectionStrategy": {
|
||||
"azure": {
|
||||
"resourceProvider": "Microsoft.DBforMySQL",
|
||||
"resourceType": "flexibleServers",
|
||||
"metrics": {},
|
||||
"logs": {
|
||||
"categoryGroups": [
|
||||
"allLogs"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"assets": {
|
||||
"dashboards": [
|
||||
{
|
||||
"id": "overview",
|
||||
"title": "Azure Database for MySQL - Flexible Server Overview",
|
||||
"description": "Overview of Azure Database for MySQL - Flexible Server metrics",
|
||||
"definition": "file://assets/dashboards/overview.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
### Monitor Azure Database for MySQL - Flexible Server with SigNoz
|
||||
|
||||
Collect key Azure Database for MySQL - Flexible Server metrics and view them with an out of the box dashboard.
|
||||
|
||||
This integration collects platform metrics for the `Microsoft.DBforMySQL/flexibleServers` resource type.
|
||||
@@ -0,0 +1 @@
|
||||
<svg id="fc890127-728b-4ac0-b5da-86cdfc191e86" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18"><defs><linearGradient id="a28dee20-4c71-46b5-b957-804c67da725a" x1="2.44" y1="10.67" x2="15.27" y2="10.67" gradientTransform="translate(0.14 -0.5) rotate(-0.01)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#005ba1"/><stop offset="0.07" stop-color="#0060a9"/><stop offset="0.36" stop-color="#0071c8"/><stop offset="0.52" stop-color="#0078d4"/><stop offset="0.64" stop-color="#0074cd"/><stop offset="0.82" stop-color="#006abb"/><stop offset="1" stop-color="#005ba1"/></linearGradient></defs><title>Icon-databases-131</title><path d="M9,5.14c-3.54,0-6.41-1-6.41-2.32V15.18c0,1.27,2.82,2.3,6.32,2.32H9c3.54,0,6.41-1,6.41-2.32V2.82C15.41,4.1,12.54,5.14,9,5.14Z" fill="url(#a28dee20-4c71-46b5-b957-804c67da725a)"/><path d="M15.41,2.82c0,1.28-2.87,2.32-6.41,2.32s-6.41-1-6.41-2.32S5.46.5,9,.5s6.41,1,6.41,2.32" fill="#e8e8e8"/><path d="M13.91,2.63c0,.82-2.2,1.48-4.91,1.48S4.08,3.45,4.08,2.64,6.28,1.16,9,1.16s4.91.66,4.91,1.47" fill="#50e6ff"/><path d="M9,3a11.65,11.65,0,0,0-3.9.57A11.53,11.53,0,0,0,9,4.11a11.47,11.47,0,0,0,3.89-.58A11.93,11.93,0,0,0,9,3Z" fill="#198ab3"/><path d="M12,9c0,.08,0,.24,0,.42a5.12,5.12,0,0,0-.08.63c0,.12,0,.3.05.46s0,.27,0,.36a1.68,1.68,0,0,1-.25.86.43.43,0,0,0,0,.07l.1.12a10.55,10.55,0,0,0,1.06-2.38h0c.28-.95.31-1.63.09-1.92a2.58,2.58,0,0,0-2.68-.86,3.29,3.29,0,0,1,.91.67A2.28,2.28,0,0,1,12,9Zm-.31.08a1.15,1.15,0,0,0-.79.09c-.29.18-.2.55,0,1a7.77,7.77,0,0,0,.35.85l.09.16h0c.05.08.08.15.11.2l.08.13a1.28,1.28,0,0,0,.18-.65,2.86,2.86,0,0,0,0-.33c0-.17,0-.36-.05-.49a6.1,6.1,0,0,1,.08-.69C11.71,9.24,11.72,9.13,11.73,9.05Zm-.3.41a.4.4,0,0,1-.18.1h0a.33.33,0,0,1-.14,0A.23.23,0,0,1,11,9.4h0c0-.07.11-.13.24-.15h.19s.09,0,.09.08A.2.2,0,0,1,11.43,9.46Zm-4.69.89c0-.07,0-.13,0-.17a1,1,0,0,0,0-.17,5.55,5.55,0,0,1,0-1A5.22,5.22,0,0,1,7,7.94,2.41,2.41,0,0,1,7.58,7,4.78,4.78,0,0,0,6.23,6.8a1.87,1.87,0,0,0-1.1.3A2,2,0,0,0,4.5,8.92,12.27,12.27,0,0,0,5,11.16c.34,1.14.73,1.84,1.07,1.95h0c.15.05.31,0,.47-.21.28-.34.54-.63.69-.8A1.88,1.88,0,0,1,6.74,10.35Zm.26.4a2.18,2.18,0,0,0,.06.56,1.5,1.5,0,0,0,.26.44,1.07,1.07,0,0,0,.35.25,1.09,1.09,0,0,0,.39.08c0-.17.14-.38.23-.6a4.35,4.35,0,0,0,.21-.59,6.61,6.61,0,0,0,0-1.11c0-.09,0-.19-.06-.3a.45.45,0,0,0-.12-.27l0,0A.66.66,0,0,0,8,9.08H7.8a1.56,1.56,0,0,0-.48.14A2,2,0,0,0,7,9.41v.11c0,.2,0,.41,0,.61v0a.86.86,0,0,1,0,.15l0,.39H7Zm.66-1.34,0,0a.46.46,0,0,1,.28,0,.6.6,0,0,1,.19.06c.09,0,.1.11.09.14h0a.37.37,0,0,1-.12.13A.3.3,0,0,1,8,9.73h0a.34.34,0,0,1-.28-.28Zm.74,3a.23.23,0,0,0-.13.06l-.14.17c-.17.21-.24.28-.73.38a.52.52,0,0,0-.26.1.58.58,0,0,0,.24.11,1.18,1.18,0,0,0,.72,0A1.7,1.7,0,0,0,8.45,13a.61.61,0,0,0,.2-.31.36.36,0,0,0-.1-.28A.15.15,0,0,0,8.4,12.39Zm4.61,0a1.63,1.63,0,0,1-1.13,0,.22.22,0,0,0-.14,0,.3.3,0,0,0-.17.14,1.09,1.09,0,0,0,0,.31,1.8,1.8,0,0,0,1.1-.1,1.36,1.36,0,0,0,.48-.34Zm-2.4-2.14c-.14-.41-.34-1,.18-1.36a1.35,1.35,0,0,1,.89-.15A3.18,3.18,0,0,0,11,7.64l-.1-.1-.06-.06h0a.34.34,0,0,0-.06-.06l0,0,0,0A2.34,2.34,0,0,0,10.11,7,2.63,2.63,0,0,0,9,6.78a1.52,1.52,0,0,0-.7.11A1.77,1.77,0,0,0,8,7a2.1,2.1,0,0,0-.74,1,5.84,5.84,0,0,0-.21,1,1.66,1.66,0,0,1,1-.23.84.84,0,0,1,.77.91,7.26,7.26,0,0,1,0,1.27,3.87,3.87,0,0,1-.23.63c-.06.17-.14.35-.18.49a.5.5,0,0,1,.38.14.66.66,0,0,1,.19.53H9c0,.08,0,.16,0,.24a6.55,6.55,0,0,0,.24,2.44.54.54,0,0,0,.24.21.6.6,0,0,0,.31.1,1.3,1.3,0,0,0,1-.34,1.05,1.05,0,0,0,.29-.66c.07-.45.22-1.7.24-2h0a.72.72,0,0,1,.09-.44.63.63,0,0,1,.27-.24A5.36,5.36,0,0,1,10.61,10.24Z" fill="#f2f2f2"/></svg>
|
||||
|
After Width: | Height: | Size: 3.4 KiB |
@@ -0,0 +1,7 @@
|
||||
### Monitor Azure Database for PostgreSQL - Flexible Server with SigNoz
|
||||
|
||||
Collect key Azure Database for PostgreSQL - Flexible Server metrics and view them with an out of the box dashboard.
|
||||
|
||||
This integration collects platform metrics for the `Microsoft.DBforPostgreSQL/flexibleServers` resource type.
|
||||
|
||||
Note: PgBouncer metrics are only emitted when the built-in PgBouncer connection pooler is enabled.
|
||||
@@ -0,0 +1 @@
|
||||
<svg id="uuid-8e49878e-6f1e-45dc-b13f-de3f3b0a3028" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18"><defs><linearGradient id="uuid-e275200f-8047-483d-9165-335881dc0492" x1=".562" y1="2.684" x2="17.561" y2="19.437" gradientTransform="translate(0 20) scale(1 -1)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#757575"/><stop offset=".915" stop-color="#b0b0b0"/></linearGradient><linearGradient id="uuid-a8467988-fb81-47a9-9300-4fac9dcb97a4" x1="13.321" y1="15.339" x2="4.581" y2="6.563" gradientTransform="translate(0 20) scale(1 -1)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#0078d4"/><stop offset="1" stop-color="#005ba1"/></linearGradient></defs><path d="M9,.5c.276,0,.5.224.5.5v1h2v-1c0-.276.224-.5.5-.5s.5.224.5.5v1h1.5c1.105,0,2,.895,2,2v1.5h1c.276,0,.5.224.5.5s-.224.5-.5.5h-1v2h1c.276,0,.5.224.5.5s-.224.5-.5.5h-1v2h1c.276,0,.5.224.5.5s-.224.5-.5.5h-1v1.5c0,1.105-.895,2-2,2h-1.5v1c0,.276-.224.5-.5.5s-.5-.224-.5-.5v-1h-2v1c0,.276-.224.5-.5.5s-.5-.224-.5-.5v-1h-2v1c0,.276-.224.5-.5.5s-.5-.224-.5-.5v-1h-1.5c-1.105,0-2-.895-2-2v-1.5h-1c-.276,0-.5-.224-.5-.5s.224-.5.5-.5h1v-2h-1c-.276,0-.5-.224-.5-.5s.224-.5.5-.5h1v-2h-1c-.276,0-.5-.224-.5-.5s.224-.5.5-.5h1v-1.5c0-1.105.895-2,2-2h1.5v-1c0-.276.224-.5.5-.5s.5.224.5.5v1h2v-1c0-.276.224-.5.5-.5ZM8.984,3h-2.968c-.005,0-.01,0-.016,0s-.011,0-.016,0h-1.984c-.552,0-1,.448-1,1v10c0,.552.448,1,1,1h1.984c.005,0,.01,0,.016,0s.011,0,.016,0h2.968c.005,0,.01,0,.016,0s.011,0,.016,0h2.968c.005,0,.01,0,.016,0,.005,0,.01,0,.016,0h1.984c.552,0,1-.448,1-1v-1.978c0-.007,0-.015,0-.022s0-.015,0-.022v-2.955c0-.007,0-.015,0-.022s0-.015,0-.022v-2.955c0-.007,0-.015,0-.022s0-.015,0-.022v-1.978c0-.552-.448-1-1-1h-1.984c-.005,0-.01,0-.016,0-.005,0-.011,0-.016,0h-2.968c-.005,0-.01,0-.016,0s-.011,0-.016,0Z" fill="url(#uuid-e275200f-8047-483d-9165-335881dc0492)" fill-rule="evenodd"/><rect x="4" y="4" width="10" height="10" rx=".5" ry=".5" fill="url(#uuid-a8467988-fb81-47a9-9300-4fac9dcb97a4)"/><path d="M12.124,9.31c-.484.567-1.007,1.214-2.053,1.214-.934,0-1.282-.765-1.307-1.387.205.402.605.728,1.229.713,1.201-.036,2.024-1.043,2.024-1.961,0-1.097-.881-1.889-2.411-1.889-1.094,0-2.45.387-3.341.998-.01.63.368,1.448.504,1.358.772-.516,1.385-.848,1.979-1.014-.879.911-2.989,3.026-3.248,3.398.029.342.484,1.259.707,1.259.068,0,.126-.036.194-.099.636-.664,1.155-1.259,1.616-1.833.065.841.51,1.869,1.754,1.869,1.114,0,2.218-.747,2.721-2.429.058-.207-.213-.369-.368-.198ZM10.855,7.952c0,.531-.562.792-1.075.792-.274,0-.485-.067-.652-.154.307-.431.61-.874.936-1.347.575.09.79.387.79.709Z" fill="#fff"/></svg>
|
||||
|
After Width: | Height: | Size: 2.5 KiB |
@@ -0,0 +1,151 @@
|
||||
{
|
||||
"id": "redis",
|
||||
"title": "Redis",
|
||||
"icon": "file://icon.svg",
|
||||
"overview": "file://overview.md",
|
||||
"supportedSignals": {
|
||||
"metrics": true,
|
||||
"logs": true
|
||||
},
|
||||
"dataCollected": {
|
||||
"metrics": [
|
||||
{
|
||||
"name": "azure_cachehits_total",
|
||||
"unit": "Count",
|
||||
"type": "Sum",
|
||||
"description": "The number of successful key lookups."
|
||||
},
|
||||
{
|
||||
"name": "azure_cachemisses_total",
|
||||
"unit": "Count",
|
||||
"type": "Sum",
|
||||
"description": "The number of failed key lookups."
|
||||
},
|
||||
{
|
||||
"name": "azure_evictedkeys_total",
|
||||
"unit": "Count",
|
||||
"type": "Sum",
|
||||
"description": "The number of items evicted from the cache."
|
||||
},
|
||||
{
|
||||
"name": "azure_expiredkeys_total",
|
||||
"unit": "Count",
|
||||
"type": "Sum",
|
||||
"description": "The number of items expired from the cache."
|
||||
},
|
||||
{
|
||||
"name": "azure_getcommands_total",
|
||||
"unit": "Count",
|
||||
"type": "Sum",
|
||||
"description": "The number of get operations from the cache."
|
||||
},
|
||||
{
|
||||
"name": "azure_setcommands_total",
|
||||
"unit": "Count",
|
||||
"type": "Sum",
|
||||
"description": "The number of set operations to the cache."
|
||||
},
|
||||
{
|
||||
"name": "azure_totalcommandsprocessed_total",
|
||||
"unit": "Count",
|
||||
"type": "Sum",
|
||||
"description": "The total number of commands processed by the cache server."
|
||||
},
|
||||
{
|
||||
"name": "azure_cachelatency_average",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "The latency to the cache in microseconds (preview)."
|
||||
},
|
||||
{
|
||||
"name": "azure_cacheread_maximum",
|
||||
"unit": "BytesPerSecond",
|
||||
"type": "Gauge",
|
||||
"description": "The amount of data read from the cache in Megabytes per second (MB/s)."
|
||||
},
|
||||
{
|
||||
"name": "azure_cachewrite_maximum",
|
||||
"unit": "BytesPerSecond",
|
||||
"type": "Gauge",
|
||||
"description": "The amount of data written to the cache in Megabytes per second (MB/s)."
|
||||
},
|
||||
{
|
||||
"name": "azure_connectedclients_maximum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "The number of client connections to the cache."
|
||||
},
|
||||
{
|
||||
"name": "azure_operationspersecond_maximum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "The number of instantaneous operations per second executed on the cache."
|
||||
},
|
||||
{
|
||||
"name": "azure_totalkeys_maximum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "The total number of items in the cache."
|
||||
},
|
||||
{
|
||||
"name": "azure_percentprocessortime_maximum",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "The CPU utilization of the Azure Redis Cache server as a percentage."
|
||||
},
|
||||
{
|
||||
"name": "azure_serverload_maximum",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "The percentage of cycles in which the Redis server is busy processing and not waiting idle for messages."
|
||||
},
|
||||
{
|
||||
"name": "azure_usedmemory_maximum",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "The amount of cache memory used for key/value pairs in the cache in MB."
|
||||
},
|
||||
{
|
||||
"name": "azure_usedmemorypercentage_maximum",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "The percentage of cache memory used for key/value pairs."
|
||||
},
|
||||
{
|
||||
"name": "azure_georeplicationhealthy_maximum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "The health of geo replication in an Active Geo-Replication group. 0 represents Unhealthy and 1 represents Healthy."
|
||||
}
|
||||
],
|
||||
"logs": [
|
||||
{
|
||||
"name": "Resource ID",
|
||||
"path": "resources.azure.resource.id",
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"telemetryCollectionStrategy": {
|
||||
"azure": {
|
||||
"resourceProvider": "Microsoft.Cache",
|
||||
"resourceType": "redisEnterprise",
|
||||
"metrics": {},
|
||||
"logs": {
|
||||
"categoryGroups": [
|
||||
"allLogs"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"assets": {
|
||||
"dashboards": [
|
||||
{
|
||||
"id": "overview",
|
||||
"title": "Azure Redis Overview",
|
||||
"description": "Overview of Azure Redis metrics",
|
||||
"definition": "file://assets/dashboards/overview.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
### Monitor Azure Redis with SigNoz
|
||||
|
||||
Collect key Azure Redis metrics and view them with an out of the box dashboard.
|
||||
|
||||
This integration collects platform metrics for the `Microsoft.Cache/redisEnterprise` resource type.
|
||||
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18"><defs><linearGradient id="f67d1585-6164-4ad0-b2dd-f9cc59b2969f" x1="9.908" y1="15.943" x2="7.516" y2="2.383" gradientUnits="userSpaceOnUse"><stop offset="0.15" stop-color="#0078d4"/><stop offset="0.8" stop-color="#5ea0ef"/><stop offset="1" stop-color="#83b9f9"/></linearGradient></defs><g id="a4fd1868-54fe-4ca6-8ff6-3b01866dc27b"><path d="M14.49,7.15A5.147,5.147,0,0,0,9.24,2.164,5.272,5.272,0,0,0,4.216,5.653,4.869,4.869,0,0,0,0,10.4a4.946,4.946,0,0,0,5.068,4.814H13.82A4.292,4.292,0,0,0,18,11.127,4.105,4.105,0,0,0,14.49,7.15Z" fill="url(#f67d1585-6164-4ad0-b2dd-f9cc59b2969f)"/><path d="M12.9,11.4V8H12v4.13h2.46V11.4ZM5.76,9.73a1.825,1.825,0,0,1-.51-.31.441.441,0,0,1-.12-.32.342.342,0,0,1,.15-.3.683.683,0,0,1,.42-.12,1.62,1.62,0,0,1,1,.29V8.11a2.58,2.58,0,0,0-1-.16,1.641,1.641,0,0,0-1.09.34,1.08,1.08,0,0,0-.42.89c0,.51.32.91,1,1.21a2.907,2.907,0,0,1,.62.36.419.419,0,0,1,.15.32.381.381,0,0,1-.16.31.806.806,0,0,1-.45.11,1.66,1.66,0,0,1-1.09-.42V12a2.173,2.173,0,0,0,1.07.24,1.877,1.877,0,0,0,1.18-.33A1.08,1.08,0,0,0,6.84,11a1.048,1.048,0,0,0-.25-.7A2.425,2.425,0,0,0,5.76,9.73ZM11,11.32A2.191,2.191,0,0,0,11,9a1.808,1.808,0,0,0-.7-.75,2,2,0,0,0-1-.26,2.112,2.112,0,0,0-1.08.27A1.856,1.856,0,0,0,7.49,9a2.465,2.465,0,0,0-.26,1.14,2.256,2.256,0,0,0,.24,1,1.766,1.766,0,0,0,.69.74,2.056,2.056,0,0,0,1,.3l.86,1h1.21L10,12.08A1.79,1.79,0,0,0,11,11.32Zm-1-.25a.941.941,0,0,1-.76.35.916.916,0,0,1-.76-.36,1.523,1.523,0,0,1-.29-1,1.529,1.529,0,0,1,.29-1,1,1,0,0,1,.78-.37.869.869,0,0,1,.75.37,1.619,1.619,0,0,1,.27,1A1.459,1.459,0,0,1,10,11.07Z" fill="#f2f2f2"/></g></svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
@@ -0,0 +1,565 @@
|
||||
{
|
||||
"id": "sqldatabase",
|
||||
"title": "SQL Database",
|
||||
"icon": "file://icon.svg",
|
||||
"overview": "file://overview.md",
|
||||
"supportedSignals": {
|
||||
"metrics": true,
|
||||
"logs": true
|
||||
},
|
||||
"dataCollected": {
|
||||
"metrics": [
|
||||
{
|
||||
"name": "azure_cpu_percent_average",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Percentage of CPU used by the database workload, relative to its limit."
|
||||
},
|
||||
{
|
||||
"name": "azure_cpu_percent_maximum",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Percentage of CPU used by the database workload, relative to its limit."
|
||||
},
|
||||
{
|
||||
"name": "azure_cpu_percent_minimum",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Percentage of CPU used by the database workload, relative to its limit."
|
||||
},
|
||||
{
|
||||
"name": "azure_sql_instance_cpu_percent_average",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Total CPU usage (user plus system) of the SQL instance, as a percentage."
|
||||
},
|
||||
{
|
||||
"name": "azure_sql_instance_cpu_percent_maximum",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Total CPU usage (user plus system) of the SQL instance, as a percentage."
|
||||
},
|
||||
{
|
||||
"name": "azure_sql_instance_cpu_percent_minimum",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Total CPU usage (user plus system) of the SQL instance, as a percentage."
|
||||
},
|
||||
{
|
||||
"name": "azure_sql_instance_memory_percent_average",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Memory usage of the SQL instance, as a percentage of its limit."
|
||||
},
|
||||
{
|
||||
"name": "azure_sql_instance_memory_percent_maximum",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Memory usage of the SQL instance, as a percentage of its limit."
|
||||
},
|
||||
{
|
||||
"name": "azure_sql_instance_memory_percent_minimum",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Memory usage of the SQL instance, as a percentage of its limit."
|
||||
},
|
||||
{
|
||||
"name": "azure_physical_data_read_percent_average",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Data file IO usage as a percentage of the limit."
|
||||
},
|
||||
{
|
||||
"name": "azure_physical_data_read_percent_maximum",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Data file IO usage as a percentage of the limit."
|
||||
},
|
||||
{
|
||||
"name": "azure_physical_data_read_percent_minimum",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Data file IO usage as a percentage of the limit."
|
||||
},
|
||||
{
|
||||
"name": "azure_log_write_percent_average",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Transaction log write throughput as a percentage of the limit."
|
||||
},
|
||||
{
|
||||
"name": "azure_log_write_percent_maximum",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Transaction log write throughput as a percentage of the limit."
|
||||
},
|
||||
{
|
||||
"name": "azure_log_write_percent_minimum",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Transaction log write throughput as a percentage of the limit."
|
||||
},
|
||||
{
|
||||
"name": "azure_workers_percent_average",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Worker threads in use as a percentage of the limit."
|
||||
},
|
||||
{
|
||||
"name": "azure_workers_percent_maximum",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Worker threads in use as a percentage of the limit."
|
||||
},
|
||||
{
|
||||
"name": "azure_workers_percent_minimum",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Worker threads in use as a percentage of the limit."
|
||||
},
|
||||
{
|
||||
"name": "azure_sessions_percent_average",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Active sessions as a percentage of the limit."
|
||||
},
|
||||
{
|
||||
"name": "azure_sessions_percent_maximum",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Active sessions as a percentage of the limit."
|
||||
},
|
||||
{
|
||||
"name": "azure_sessions_percent_minimum",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Active sessions as a percentage of the limit."
|
||||
},
|
||||
{
|
||||
"name": "azure_sessions_count_average",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Number of active sessions."
|
||||
},
|
||||
{
|
||||
"name": "azure_sessions_count_maximum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Number of active sessions."
|
||||
},
|
||||
{
|
||||
"name": "azure_sessions_count_minimum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Number of active sessions."
|
||||
},
|
||||
{
|
||||
"name": "azure_dtu_consumption_percent_average",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "DTU consumption as a percentage of the limit (DTU-based purchasing model)."
|
||||
},
|
||||
{
|
||||
"name": "azure_dtu_consumption_percent_maximum",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "DTU consumption as a percentage of the limit (DTU-based purchasing model)."
|
||||
},
|
||||
{
|
||||
"name": "azure_dtu_consumption_percent_minimum",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "DTU consumption as a percentage of the limit (DTU-based purchasing model)."
|
||||
},
|
||||
{
|
||||
"name": "azure_dtu_used_average",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "DTUs used (DTU-based purchasing model)."
|
||||
},
|
||||
{
|
||||
"name": "azure_dtu_used_maximum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "DTUs used (DTU-based purchasing model)."
|
||||
},
|
||||
{
|
||||
"name": "azure_dtu_used_minimum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "DTUs used (DTU-based purchasing model)."
|
||||
},
|
||||
{
|
||||
"name": "azure_dtu_limit_average",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "DTU limit (DTU-based purchasing model)."
|
||||
},
|
||||
{
|
||||
"name": "azure_dtu_limit_maximum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "DTU limit (DTU-based purchasing model)."
|
||||
},
|
||||
{
|
||||
"name": "azure_dtu_limit_minimum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "DTU limit (DTU-based purchasing model)."
|
||||
},
|
||||
{
|
||||
"name": "azure_cpu_used_average",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "vCores used (vCore-based purchasing model)."
|
||||
},
|
||||
{
|
||||
"name": "azure_cpu_used_maximum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "vCores used (vCore-based purchasing model)."
|
||||
},
|
||||
{
|
||||
"name": "azure_cpu_used_minimum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "vCores used (vCore-based purchasing model)."
|
||||
},
|
||||
{
|
||||
"name": "azure_cpu_limit_average",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "vCore limit (vCore-based purchasing model)."
|
||||
},
|
||||
{
|
||||
"name": "azure_cpu_limit_maximum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "vCore limit (vCore-based purchasing model)."
|
||||
},
|
||||
{
|
||||
"name": "azure_cpu_limit_minimum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "vCore limit (vCore-based purchasing model)."
|
||||
},
|
||||
{
|
||||
"name": "azure_storage_average",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Data space used by the database."
|
||||
},
|
||||
{
|
||||
"name": "azure_storage_maximum",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Data space used by the database."
|
||||
},
|
||||
{
|
||||
"name": "azure_storage_minimum",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Data space used by the database."
|
||||
},
|
||||
{
|
||||
"name": "azure_storage_percent_average",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Data space used as a percentage of the maximum data size."
|
||||
},
|
||||
{
|
||||
"name": "azure_storage_percent_maximum",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Data space used as a percentage of the maximum data size."
|
||||
},
|
||||
{
|
||||
"name": "azure_storage_percent_minimum",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Data space used as a percentage of the maximum data size."
|
||||
},
|
||||
{
|
||||
"name": "azure_allocated_data_storage_average",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Data space allocated to the database (includes unused space)."
|
||||
},
|
||||
{
|
||||
"name": "azure_allocated_data_storage_maximum",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Data space allocated to the database (includes unused space)."
|
||||
},
|
||||
{
|
||||
"name": "azure_allocated_data_storage_minimum",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Data space allocated to the database (includes unused space)."
|
||||
},
|
||||
{
|
||||
"name": "azure_xtp_storage_percent_average",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "In-Memory OLTP storage used as a percentage of the limit."
|
||||
},
|
||||
{
|
||||
"name": "azure_xtp_storage_percent_maximum",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "In-Memory OLTP storage used as a percentage of the limit."
|
||||
},
|
||||
{
|
||||
"name": "azure_xtp_storage_percent_minimum",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "In-Memory OLTP storage used as a percentage of the limit."
|
||||
},
|
||||
{
|
||||
"name": "azure_full_backup_size_bytes_average",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Cumulative full backup storage size."
|
||||
},
|
||||
{
|
||||
"name": "azure_full_backup_size_bytes_maximum",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Cumulative full backup storage size."
|
||||
},
|
||||
{
|
||||
"name": "azure_full_backup_size_bytes_minimum",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Cumulative full backup storage size."
|
||||
},
|
||||
{
|
||||
"name": "azure_diff_backup_size_bytes_average",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Cumulative differential backup storage size."
|
||||
},
|
||||
{
|
||||
"name": "azure_diff_backup_size_bytes_maximum",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Cumulative differential backup storage size."
|
||||
},
|
||||
{
|
||||
"name": "azure_diff_backup_size_bytes_minimum",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Cumulative differential backup storage size."
|
||||
},
|
||||
{
|
||||
"name": "azure_log_backup_size_bytes_average",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Cumulative transaction log backup storage size."
|
||||
},
|
||||
{
|
||||
"name": "azure_log_backup_size_bytes_maximum",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Cumulative transaction log backup storage size."
|
||||
},
|
||||
{
|
||||
"name": "azure_log_backup_size_bytes_minimum",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Cumulative transaction log backup storage size."
|
||||
},
|
||||
{
|
||||
"name": "azure_replication_lag_seconds_average",
|
||||
"unit": "Seconds",
|
||||
"type": "Gauge",
|
||||
"description": "Geo-replication lag (RPO) in seconds; reported on the primary database only."
|
||||
},
|
||||
{
|
||||
"name": "azure_replication_lag_seconds_maximum",
|
||||
"unit": "Seconds",
|
||||
"type": "Gauge",
|
||||
"description": "Geo-replication lag (RPO) in seconds; reported on the primary database only."
|
||||
},
|
||||
{
|
||||
"name": "azure_replication_lag_seconds_minimum",
|
||||
"unit": "Seconds",
|
||||
"type": "Gauge",
|
||||
"description": "Geo-replication lag (RPO) in seconds; reported on the primary database only."
|
||||
},
|
||||
{
|
||||
"name": "azure_connection_successful_total",
|
||||
"unit": "Count",
|
||||
"type": "Sum",
|
||||
"description": "Number of successful connections."
|
||||
},
|
||||
{
|
||||
"name": "azure_connection_successful_count",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Number of successful connections."
|
||||
},
|
||||
{
|
||||
"name": "azure_connection_failed_total",
|
||||
"unit": "Count",
|
||||
"type": "Sum",
|
||||
"description": "Number of failed connections caused by system errors."
|
||||
},
|
||||
{
|
||||
"name": "azure_connection_failed_count",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Number of failed connections caused by system errors."
|
||||
},
|
||||
{
|
||||
"name": "azure_connection_failed_user_error_total",
|
||||
"unit": "Count",
|
||||
"type": "Sum",
|
||||
"description": "Number of failed connections caused by user errors."
|
||||
},
|
||||
{
|
||||
"name": "azure_connection_failed_user_error_count",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Number of failed connections caused by user errors."
|
||||
},
|
||||
{
|
||||
"name": "azure_blocked_by_firewall_total",
|
||||
"unit": "Count",
|
||||
"type": "Sum",
|
||||
"description": "Number of connection attempts blocked by the firewall."
|
||||
},
|
||||
{
|
||||
"name": "azure_blocked_by_firewall_count",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Number of connection attempts blocked by the firewall."
|
||||
},
|
||||
{
|
||||
"name": "azure_deadlock_total",
|
||||
"unit": "Count",
|
||||
"type": "Sum",
|
||||
"description": "Number of deadlocks."
|
||||
},
|
||||
{
|
||||
"name": "azure_deadlock_count",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Number of deadlocks."
|
||||
},
|
||||
{
|
||||
"name": "azure_availability_average",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Database availability percentage (100 if connections succeed, 0 if all fail) per minute."
|
||||
},
|
||||
{
|
||||
"name": "azure_availability_maximum",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Database availability percentage (100 if connections succeed, 0 if all fail) per minute."
|
||||
},
|
||||
{
|
||||
"name": "azure_availability_minimum",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Database availability percentage (100 if connections succeed, 0 if all fail) per minute."
|
||||
},
|
||||
{
|
||||
"name": "azure_availability_count",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Database availability percentage (100 if connections succeed, 0 if all fail) per minute."
|
||||
},
|
||||
{
|
||||
"name": "azure_availability_total",
|
||||
"unit": "Percent",
|
||||
"type": "Sum",
|
||||
"description": "Database availability percentage (100 if connections succeed, 0 if all fail) per minute."
|
||||
},
|
||||
{
|
||||
"name": "azure_tempdb_data_size_average",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Space used in tempdb data files, in kilobytes."
|
||||
},
|
||||
{
|
||||
"name": "azure_tempdb_data_size_maximum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Space used in tempdb data files, in kilobytes."
|
||||
},
|
||||
{
|
||||
"name": "azure_tempdb_data_size_minimum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Space used in tempdb data files, in kilobytes."
|
||||
},
|
||||
{
|
||||
"name": "azure_tempdb_log_size_average",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Space used in the tempdb transaction log file, in kilobytes."
|
||||
},
|
||||
{
|
||||
"name": "azure_tempdb_log_size_maximum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Space used in the tempdb transaction log file, in kilobytes."
|
||||
},
|
||||
{
|
||||
"name": "azure_tempdb_log_size_minimum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Space used in the tempdb transaction log file, in kilobytes."
|
||||
},
|
||||
{
|
||||
"name": "azure_tempdb_log_used_percent_average",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "tempdb transaction log space used as a percentage."
|
||||
},
|
||||
{
|
||||
"name": "azure_tempdb_log_used_percent_maximum",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "tempdb transaction log space used as a percentage."
|
||||
},
|
||||
{
|
||||
"name": "azure_tempdb_log_used_percent_minimum",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "tempdb transaction log space used as a percentage."
|
||||
}
|
||||
],
|
||||
"logs": [
|
||||
{
|
||||
"name": "Resource ID",
|
||||
"path": "resources.azure.resource.id",
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"telemetryCollectionStrategy": {
|
||||
"azure": {
|
||||
"resourceProvider": "Microsoft.Sql",
|
||||
"resourceType": "servers/databases",
|
||||
"metrics": {},
|
||||
"logs": {
|
||||
"categoryGroups": [
|
||||
"allLogs"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"assets": {
|
||||
"dashboards": [
|
||||
{
|
||||
"id": "overview",
|
||||
"title": "Azure SQL Database Overview",
|
||||
"description": "Overview of Azure SQL Database metrics",
|
||||
"definition": "file://assets/dashboards/overview.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
### Monitor Azure SQL Database with SigNoz
|
||||
|
||||
Collect key Azure SQL Database (single database) metrics and view them with an out of the box dashboard.
|
||||
|
||||
This integration collects platform metrics for the `Microsoft.Sql/servers/databases` resource type.
|
||||
|
||||
Note: This integration is for Azure SQL Database (the PaaS offering). Azure SQL Managed Instance and SQL Server on Azure VMs expose a different set of metrics and are not covered here.
|
||||
@@ -0,0 +1 @@
|
||||
<svg id="a5c93a83-9fd9-4ccb-ba77-53d6c609a7d3" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18"><defs><linearGradient id="acf2da4b-8aca-4b58-b995-ca6956cf663e" x1="5.41" y1="17.33" x2="5.41" y2="0.61" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#949494"/><stop offset="0.53" stop-color="#a2a2a2"/><stop offset="1" stop-color="#b3b3b3"/></linearGradient><linearGradient id="b152b416-25c2-4a4a-9d7f-a0bb2a13f84a" x1="10.04" y1="17.39" x2="10.04" y2="6.82" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#0078d4"/><stop offset="0.16" stop-color="#1380da"/><stop offset="0.53" stop-color="#3c91e5"/><stop offset="0.82" stop-color="#559cec"/><stop offset="1" stop-color="#5ea0ef"/></linearGradient></defs><title>Icon-databases-136</title><path d="M10.32,16.76a.58.58,0,0,1-.57.57H1.07a.57.57,0,0,1-.57-.57V1.18A.56.56,0,0,1,1.07.61H9.75a.57.57,0,0,1,.57.57Z" fill="url(#acf2da4b-8aca-4b58-b995-ca6956cf663e)"/><path d="M1.94,6.47A1.07,1.07,0,0,1,3,5.41H7.9A1.07,1.07,0,0,1,9,6.47H9A1.07,1.07,0,0,1,7.9,7.54H3A1.07,1.07,0,0,1,1.94,6.47Z" fill="#003067"/><path d="M1.94,3.31A1.07,1.07,0,0,1,3,2.24H7.9A1.07,1.07,0,0,1,9,3.31H9A1.07,1.07,0,0,1,7.9,4.37H3A1.07,1.07,0,0,1,1.94,3.31Z" fill="#003067"/><circle cx="3.06" cy="3.31" r="0.72" fill="#50e6ff"/><circle cx="3.06" cy="6.47" r="0.72" fill="#50e6ff"/><path d="M17.5,14.08a3.36,3.36,0,0,0-2.91-3.22,4.22,4.22,0,0,0-4.35-4A4.32,4.32,0,0,0,6.1,9.64a4,4,0,0,0-3.52,3.85,4.06,4.06,0,0,0,4.2,3.9l.37,0H14l.17,0A3.39,3.39,0,0,0,17.5,14.08Z" fill="url(#b152b416-25c2-4a4a-9d7f-a0bb2a13f84a)"/><path d="M13.61,14.45V11.09h-.93v4.12h2.45v-.76ZM6.51,12.8A2.23,2.23,0,0,1,6,12.49a.44.44,0,0,1-.12-.32.34.34,0,0,1,.15-.3.66.66,0,0,1,.42-.12,1.66,1.66,0,0,1,1,.29v-.86a2.89,2.89,0,0,0-1-.15,1.69,1.69,0,0,0-1.09.33,1.1,1.1,0,0,0-.41.89,1.34,1.34,0,0,0,.94,1.2,2.51,2.51,0,0,1,.61.36.42.42,0,0,1,.15.32.34.34,0,0,1-.15.3.75.75,0,0,1-.45.12,1.63,1.63,0,0,1-1.08-.42v.92A2.25,2.25,0,0,0,6,15.28,1.91,1.91,0,0,0,7.15,15a1.07,1.07,0,0,0,.43-.91,1,1,0,0,0-.25-.7A2.36,2.36,0,0,0,6.51,12.8Zm5.16,1.58A2.37,2.37,0,0,0,12,13.12,2.28,2.28,0,0,0,11.75,12a1.77,1.77,0,0,0-.69-.74A1.94,1.94,0,0,0,10,11,2.21,2.21,0,0,0,9,11.29a1.87,1.87,0,0,0-.73.77A2.52,2.52,0,0,0,8,13.2a2.26,2.26,0,0,0,.24,1.05,1.87,1.87,0,0,0,.68.74,2,2,0,0,0,1,.29l.85,1h1.2l-1.19-1.1A1.82,1.82,0,0,0,11.67,14.38Zm-.93-.25a.92.92,0,0,1-.76.35.91.91,0,0,1-.75-.36,1.5,1.5,0,0,1-.28-1,1.46,1.46,0,0,1,.29-1,.92.92,0,0,1,.77-.37.86.86,0,0,1,.74.37,1.54,1.54,0,0,1,.28,1A1.47,1.47,0,0,1,10.74,14.13Z" fill="#f2f2f2"/></svg>
|
||||
|
After Width: | Height: | Size: 2.5 KiB |
@@ -0,0 +1,167 @@
|
||||
{
|
||||
"id": "sqldatabasemi",
|
||||
"title": "SQL Database Managed Instance",
|
||||
"icon": "file://icon.svg",
|
||||
"overview": "file://overview.md",
|
||||
"supportedSignals": {
|
||||
"metrics": true,
|
||||
"logs": true
|
||||
},
|
||||
"dataCollected": {
|
||||
"metrics": [
|
||||
{
|
||||
"name": "azure_avg_cpu_percent_average",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Average CPU utilization of the managed instance, as a percentage."
|
||||
},
|
||||
{
|
||||
"name": "azure_avg_cpu_percent_maximum",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Maximum CPU utilization of the managed instance, as a percentage."
|
||||
},
|
||||
{
|
||||
"name": "azure_avg_cpu_percent_minimum",
|
||||
"unit": "Percent",
|
||||
"type": "Gauge",
|
||||
"description": "Minimum CPU utilization of the managed instance, as a percentage."
|
||||
},
|
||||
{
|
||||
"name": "azure_io_bytes_read_average",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Average bytes read from storage by the managed instance."
|
||||
},
|
||||
{
|
||||
"name": "azure_io_bytes_read_maximum",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Maximum bytes read from storage by the managed instance."
|
||||
},
|
||||
{
|
||||
"name": "azure_io_bytes_read_minimum",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Minimum bytes read from storage by the managed instance."
|
||||
},
|
||||
{
|
||||
"name": "azure_io_bytes_written_average",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Average bytes written to storage by the managed instance."
|
||||
},
|
||||
{
|
||||
"name": "azure_io_bytes_written_maximum",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Maximum bytes written to storage by the managed instance."
|
||||
},
|
||||
{
|
||||
"name": "azure_io_bytes_written_minimum",
|
||||
"unit": "Bytes",
|
||||
"type": "Gauge",
|
||||
"description": "Minimum bytes written to storage by the managed instance."
|
||||
},
|
||||
{
|
||||
"name": "azure_io_requests_average",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Average number of storage IO requests made by the managed instance."
|
||||
},
|
||||
{
|
||||
"name": "azure_io_requests_maximum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Maximum number of storage IO requests made by the managed instance."
|
||||
},
|
||||
{
|
||||
"name": "azure_io_requests_minimum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Minimum number of storage IO requests made by the managed instance."
|
||||
},
|
||||
{
|
||||
"name": "azure_reserved_storage_mb_average",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Average storage space reserved for the managed instance, in megabytes."
|
||||
},
|
||||
{
|
||||
"name": "azure_reserved_storage_mb_maximum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Maximum storage space reserved for the managed instance, in megabytes."
|
||||
},
|
||||
{
|
||||
"name": "azure_reserved_storage_mb_minimum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Minimum storage space reserved for the managed instance, in megabytes."
|
||||
},
|
||||
{
|
||||
"name": "azure_storage_space_used_mb_average",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Average storage space used by the managed instance, in megabytes."
|
||||
},
|
||||
{
|
||||
"name": "azure_storage_space_used_mb_maximum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Maximum storage space used by the managed instance, in megabytes."
|
||||
},
|
||||
{
|
||||
"name": "azure_storage_space_used_mb_minimum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Minimum storage space used by the managed instance, in megabytes."
|
||||
},
|
||||
{
|
||||
"name": "azure_virtual_core_count_average",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Average number of virtual cores provisioned for the managed instance."
|
||||
},
|
||||
{
|
||||
"name": "azure_virtual_core_count_maximum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Maximum number of virtual cores provisioned for the managed instance."
|
||||
},
|
||||
{
|
||||
"name": "azure_virtual_core_count_minimum",
|
||||
"unit": "Count",
|
||||
"type": "Gauge",
|
||||
"description": "Minimum number of virtual cores provisioned for the managed instance."
|
||||
}
|
||||
],
|
||||
"logs": [
|
||||
{
|
||||
"name": "Resource ID",
|
||||
"path": "resources.azure.resource.id",
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"telemetryCollectionStrategy": {
|
||||
"azure": {
|
||||
"resourceProvider": "Microsoft.Sql",
|
||||
"resourceType": "managedInstances",
|
||||
"metrics": {},
|
||||
"logs": {
|
||||
"categoryGroups": ["allLogs"]
|
||||
}
|
||||
}
|
||||
},
|
||||
"assets": {
|
||||
"dashboards": [
|
||||
{
|
||||
"id": "overview",
|
||||
"title": "Azure SQL Database Managed Instance Overview",
|
||||
"description": "Overview of Azure SQL Database Managed Instance metrics",
|
||||
"definition": "file://assets/dashboards/overview.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
### Monitor Azure SQL Database Managed Instance with SigNoz
|
||||
|
||||
Collect key Azure SQL Database Managed Instance metrics and view them with an out of the box dashboard.
|
||||
|
||||
This integration collects platform metrics for the `Microsoft.Sql/managedInstances` resource type.
|
||||
@@ -59,6 +59,8 @@ type Module interface {
|
||||
|
||||
CreateV2(ctx context.Context, orgID valuer.UUID, createdBy string, creator valuer.UUID, source dashboardtypes.Source, postable dashboardtypes.PostableDashboardV2) (*dashboardtypes.DashboardV2, error)
|
||||
|
||||
CloneV2(ctx context.Context, orgID valuer.UUID, createdBy string, creator valuer.UUID, id valuer.UUID) (*dashboardtypes.DashboardV2, error)
|
||||
|
||||
GetV2(ctx context.Context, orgID valuer.UUID, id valuer.UUID) (*dashboardtypes.DashboardV2, error)
|
||||
|
||||
ListV2(ctx context.Context, orgID valuer.UUID, params *dashboardtypes.ListDashboardsV2Params) (*dashboardtypes.ListableDashboardV2, error)
|
||||
@@ -106,6 +108,8 @@ type Handler interface {
|
||||
// ════════════════════════════════════════════════════════════════════════
|
||||
CreateV2(http.ResponseWriter, *http.Request)
|
||||
|
||||
CloneV2(http.ResponseWriter, *http.Request)
|
||||
|
||||
GetV2(http.ResponseWriter, *http.Request)
|
||||
|
||||
ListV2(http.ResponseWriter, *http.Request)
|
||||
|
||||
@@ -42,6 +42,38 @@ func (handler *handler) CreateV2(rw http.ResponseWriter, r *http.Request) {
|
||||
render.Success(rw, http.StatusCreated, dashboard.ToGettableDashboardV2())
|
||||
}
|
||||
|
||||
func (handler *handler) CloneV2(rw http.ResponseWriter, r *http.Request) {
|
||||
ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second)
|
||||
defer cancel()
|
||||
|
||||
claims, err := authtypes.ClaimsFromContext(ctx)
|
||||
if err != nil {
|
||||
render.Error(rw, err)
|
||||
return
|
||||
}
|
||||
|
||||
orgID := valuer.MustNewUUID(claims.OrgID)
|
||||
|
||||
id := mux.Vars(r)["id"]
|
||||
if id == "" {
|
||||
render.Error(rw, errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "id is missing in the path"))
|
||||
return
|
||||
}
|
||||
dashboardID, err := valuer.NewUUID(id)
|
||||
if err != nil {
|
||||
render.Error(rw, err)
|
||||
return
|
||||
}
|
||||
|
||||
dashboard, err := handler.module.CloneV2(ctx, orgID, claims.Email, valuer.MustNewUUID(claims.IdentityID()), dashboardID)
|
||||
if err != nil {
|
||||
render.Error(rw, err)
|
||||
return
|
||||
}
|
||||
|
||||
render.Success(rw, http.StatusCreated, dashboard.ToGettableDashboardV2())
|
||||
}
|
||||
|
||||
func (handler *handler) ListV2(rw http.ResponseWriter, r *http.Request) {
|
||||
ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second)
|
||||
defer cancel()
|
||||
|
||||
@@ -43,6 +43,18 @@ func (m *module) CreateV2(ctx context.Context, orgID valuer.UUID, createdBy stri
|
||||
return dashboard, nil
|
||||
}
|
||||
|
||||
func (m *module) CloneV2(ctx context.Context, orgID valuer.UUID, createdBy string, creator valuer.UUID, id valuer.UUID) (*dashboardtypes.DashboardV2, error) {
|
||||
existing, err := m.GetV2(ctx, orgID, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := existing.ErrIfNotClonable(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return m.CreateV2(ctx, orgID, createdBy, creator, dashboardtypes.SourceUser, existing.ToPostableForCloning())
|
||||
}
|
||||
|
||||
func (module *module) ListV2(ctx context.Context, orgID valuer.UUID, params *dashboardtypes.ListDashboardsV2Params) (*dashboardtypes.ListableDashboardV2, error) {
|
||||
dashboards, total, err := module.store.ListV2(ctx, orgID, params)
|
||||
if err != nil {
|
||||
|
||||
32
pkg/modules/inframonitoring/implinframonitoring/collect.go
Normal file
@@ -0,0 +1,32 @@
|
||||
package implinframonitoring
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/errors"
|
||||
"github.com/SigNoz/signoz/pkg/telemetrymetrics"
|
||||
"github.com/SigNoz/signoz/pkg/valuer"
|
||||
)
|
||||
|
||||
func (m *module) Collect(ctx context.Context, _ valuer.UUID) (map[string]any, error) {
|
||||
stats := make(map[string]any)
|
||||
|
||||
metadataTable := fmt.Sprintf("%s.%s", telemetrymetrics.DBName, telemetrymetrics.AttributesMetadataTableName)
|
||||
var (
|
||||
systemMetricCount uint64
|
||||
k8sMetricCount uint64
|
||||
)
|
||||
query := fmt.Sprintf(
|
||||
"SELECT (SELECT count() FROM (SELECT 1 FROM %s WHERE metric_name LIKE 'system.%%' LIMIT 1)), (SELECT count() FROM (SELECT 1 FROM %s WHERE metric_name LIKE 'k8s.%%' LIMIT 1))",
|
||||
metadataTable, metadataTable,
|
||||
)
|
||||
if err := m.telemetryStore.ClickhouseDB().QueryRow(ctx, query).Scan(&systemMetricCount, &k8sMetricCount); err == nil {
|
||||
stats["telemetry.metrics.system.exists"] = systemMetricCount > 0
|
||||
stats["telemetry.metrics.k8s.exists"] = k8sMetricCount > 0
|
||||
} else {
|
||||
m.logger.DebugContext(ctx, "failed to collect metrics namespace existence stats", errors.Attr(err))
|
||||
}
|
||||
|
||||
return stats, nil
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/SigNoz/signoz/pkg/statsreporter"
|
||||
"github.com/SigNoz/signoz/pkg/types/inframonitoringtypes"
|
||||
"github.com/SigNoz/signoz/pkg/valuer"
|
||||
)
|
||||
@@ -22,6 +23,7 @@ type Handler interface {
|
||||
}
|
||||
|
||||
type Module interface {
|
||||
statsreporter.StatsCollector
|
||||
ListHosts(ctx context.Context, orgID valuer.UUID, req *inframonitoringtypes.PostableHosts) (*inframonitoringtypes.Hosts, error)
|
||||
ListPods(ctx context.Context, orgID valuer.UUID, req *inframonitoringtypes.PostablePods) (*inframonitoringtypes.Pods, error)
|
||||
ListNodes(ctx context.Context, orgID valuer.UUID, req *inframonitoringtypes.PostableNodes) (*inframonitoringtypes.Nodes, error)
|
||||
|
||||
@@ -744,6 +744,32 @@ func (m *Manager) TriggeredAlerts() []*ruletypes.NamedAlert {
|
||||
return namedAlerts
|
||||
}
|
||||
|
||||
type AlertStats struct {
|
||||
FiringRules int64
|
||||
LastFiredAt time.Time
|
||||
}
|
||||
|
||||
func (m *Manager) AlertStats(ctx context.Context) AlertStats {
|
||||
m.mtx.RLock()
|
||||
defer m.mtx.RUnlock()
|
||||
|
||||
// TODO(therealpandey): scope these stats per org; rules for all orgs are aggregated here.
|
||||
stats := AlertStats{}
|
||||
for _, r := range m.rules {
|
||||
if r.State() == ruletypes.StateFiring {
|
||||
stats.FiringRules++
|
||||
}
|
||||
|
||||
for _, alert := range r.ActiveAlerts() {
|
||||
if alert.FiredAt.After(stats.LastFiredAt) {
|
||||
stats.LastFiredAt = alert.FiredAt
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return stats
|
||||
}
|
||||
|
||||
// NotifyFunc sends notifications about a set of alerts generated by the given expression.
|
||||
type NotifyFunc func(ctx context.Context, orgID string, alerts ...*ruletypes.Alert)
|
||||
|
||||
|
||||
@@ -100,7 +100,16 @@ func (provider *provider) Collect(ctx context.Context, orgID valuer.UUID) (map[s
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ruletypes.NewStatsFromRules(rules), nil
|
||||
stats := ruletypes.NewStatsFromRules(rules)
|
||||
|
||||
alertStats := provider.manager.AlertStats(ctx)
|
||||
stats["alert.firing.count"] = alertStats.FiringRules
|
||||
if !alertStats.LastFiredAt.IsZero() {
|
||||
stats["alert.last_fired.time"] = alertStats.LastFiredAt.UTC()
|
||||
stats["alert.last_fired.time_unix"] = alertStats.LastFiredAt.Unix()
|
||||
}
|
||||
|
||||
return stats, nil
|
||||
}
|
||||
|
||||
func (provider *provider) ListRuleStates(ctx context.Context) (*ruletypes.GettableRules, error) {
|
||||
|
||||
@@ -499,6 +499,7 @@ func New(
|
||||
serviceAccount,
|
||||
cloudIntegrationModule,
|
||||
modules.LogsPipeline,
|
||||
modules.InfraMonitoring,
|
||||
querier,
|
||||
}
|
||||
|
||||
|
||||
@@ -25,12 +25,20 @@ var (
|
||||
AWSServiceSQS = ServiceID{valuer.NewString("sqs")}
|
||||
|
||||
// Azure services.
|
||||
AzureServiceStorageAccountsBlob = ServiceID{valuer.NewString("storageaccountsblob")}
|
||||
AzureServiceCDNProfile = ServiceID{valuer.NewString("cdnprofile")}
|
||||
AzureServiceVirtualMachine = ServiceID{valuer.NewString("virtualmachine")}
|
||||
AzureServiceAppService = ServiceID{valuer.NewString("appservice")}
|
||||
AzureServiceContainerApp = ServiceID{valuer.NewString("containerapp")}
|
||||
AzureServiceAKS = ServiceID{valuer.NewString("aks")}
|
||||
AzureServiceStorageAccountsBlob = ServiceID{valuer.NewString("storageaccountsblob")}
|
||||
AzureServiceCDNProfile = ServiceID{valuer.NewString("cdnprofile")}
|
||||
AzureServiceVirtualMachine = ServiceID{valuer.NewString("virtualmachine")}
|
||||
AzureServiceAppService = ServiceID{valuer.NewString("appservice")}
|
||||
AzureServiceContainerApp = ServiceID{valuer.NewString("containerapp")}
|
||||
AzureServiceAKS = ServiceID{valuer.NewString("aks")}
|
||||
AzureServiceSQLDatabase = ServiceID{valuer.NewString("sqldatabase")}
|
||||
AzureServiceSQLDatabaseManagedInstance = ServiceID{valuer.NewString("sqldatabasemi")}
|
||||
AzureServiceMySQLFlexibleServer = ServiceID{valuer.NewString("mysqlflexibleserver")}
|
||||
AzureServicePostgreSQLFlexibleServer = ServiceID{valuer.NewString("postgresqlflexibleserver")}
|
||||
AzureServiceMongoDB = ServiceID{valuer.NewString("mongodb")}
|
||||
AzureServiceCosmosDB = ServiceID{valuer.NewString("cosmosdb")}
|
||||
AzureServiceCassandraDB = ServiceID{valuer.NewString("cassandradb")}
|
||||
AzureServiceRedis = ServiceID{valuer.NewString("redis")}
|
||||
)
|
||||
|
||||
func (ServiceID) Enum() []any {
|
||||
@@ -54,6 +62,14 @@ func (ServiceID) Enum() []any {
|
||||
AzureServiceAppService,
|
||||
AzureServiceContainerApp,
|
||||
AzureServiceAKS,
|
||||
AzureServiceSQLDatabase,
|
||||
AzureServiceSQLDatabaseManagedInstance,
|
||||
AzureServiceMySQLFlexibleServer,
|
||||
AzureServicePostgreSQLFlexibleServer,
|
||||
AzureServiceMongoDB,
|
||||
AzureServiceCosmosDB,
|
||||
AzureServiceCassandraDB,
|
||||
AzureServiceRedis,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,6 +97,14 @@ var SupportedServices = map[CloudProviderType][]ServiceID{
|
||||
AzureServiceAppService,
|
||||
AzureServiceContainerApp,
|
||||
AzureServiceAKS,
|
||||
AzureServiceSQLDatabase,
|
||||
AzureServiceSQLDatabaseManagedInstance,
|
||||
AzureServiceMySQLFlexibleServer,
|
||||
AzureServicePostgreSQLFlexibleServer,
|
||||
AzureServiceMongoDB,
|
||||
AzureServiceCosmosDB,
|
||||
AzureServiceCassandraDB,
|
||||
AzureServiceRedis,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -126,6 +126,22 @@ func (d *DashboardV2) ErrIfNotDeletable() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *DashboardV2) ErrIfNotClonable() error {
|
||||
if !d.Source.isClonable() {
|
||||
return errors.Newf(errors.TypeInvalidInput, ErrCodeDashboardImmutable, "%s dashboards cannot be cloned", d.Source)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d DashboardV2) ToPostableForCloning() PostableDashboardV2 {
|
||||
return PostableDashboardV2{
|
||||
DashboardV2MetadataBase: d.DashboardV2MetadataBase,
|
||||
GenerateName: true,
|
||||
Tags: tagtypes.NewPostableTagsFromTags(d.Tags),
|
||||
Spec: d.Spec,
|
||||
}
|
||||
}
|
||||
|
||||
type DashboardV2MetadataBase struct {
|
||||
SchemaVersion string `json:"schemaVersion" required:"true"`
|
||||
Image string `json:"image,omitempty"`
|
||||
|
||||
@@ -202,6 +202,24 @@ func TestDashboardV2ToGettableDashboardV2(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestDashboardV2ToPostableForCloning(t *testing.T) {
|
||||
orgID := valuer.GenerateUUID()
|
||||
dashboard := newTestDashboardV2(t, orgID, SourceUser)
|
||||
|
||||
postable := dashboard.ToPostableForCloning()
|
||||
|
||||
assert.True(t, postable.GenerateName, "internal name must be regenerated, not copied")
|
||||
assert.Empty(t, postable.Name, "name must be empty so generateName can derive it")
|
||||
assert.Equal(t, dashboard.DashboardV2MetadataBase, postable.DashboardV2MetadataBase, "schema version and image are carried over")
|
||||
assert.Equal(t, dashboard.Spec, postable.Spec, "spec (incl. display name) is preserved verbatim")
|
||||
|
||||
require.Len(t, postable.Tags, len(dashboard.Tags))
|
||||
for i, sourceTag := range dashboard.Tags {
|
||||
assert.Equal(t, sourceTag.Key, postable.Tags[i].Key)
|
||||
assert.Equal(t, sourceTag.Value, postable.Tags[i].Value)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDashboardV2StorableRoundTrip(t *testing.T) {
|
||||
orgID := valuer.GenerateUUID()
|
||||
original := newTestDashboardV2(t, orgID, SourceIntegration)
|
||||
|
||||
@@ -55,6 +55,10 @@ func (s Source) isUserDeletable() bool {
|
||||
return s == SourceUser
|
||||
}
|
||||
|
||||
func (s Source) isClonable() bool {
|
||||
return s == SourceUser || s == SourceIntegration
|
||||
}
|
||||
|
||||
func NewSource(source string) (Source, error) {
|
||||
candidate := Source{s: valuer.NewString(source)}
|
||||
if !candidate.IsValid() {
|
||||
|
||||
@@ -686,6 +686,28 @@ def test_dashboard_v2_lifecycle( # pylint: disable=too-many-locals,too-many-sta
|
||||
"Zeta Overview",
|
||||
}
|
||||
|
||||
# ── stage 11: clone keeps the display name but mints a new, retrievable one ─
|
||||
response = requests.post(
|
||||
signoz.self.host_configs["8080"].get(f"{BASE_URL}/{ids['lc-alpha']}/clone"),
|
||||
headers={"Authorization": f"Bearer {token}"},
|
||||
timeout=5,
|
||||
)
|
||||
assert response.status_code == HTTPStatus.CREATED, response.text
|
||||
clone = response.json()["data"]
|
||||
assert clone["id"] != ids["lc-alpha"]
|
||||
assert clone["name"] != "lc-alpha" # internal name is regenerated
|
||||
assert clone["spec"]["display"]["name"] == "Alpha Overview" # display name preserved
|
||||
assert clone["source"] == "user"
|
||||
assert clone["locked"] is False
|
||||
|
||||
response = requests.get(
|
||||
signoz.self.host_configs["8080"].get(f"{BASE_URL}/{clone['id']}"),
|
||||
headers={"Authorization": f"Bearer {token}"},
|
||||
timeout=5,
|
||||
)
|
||||
assert response.status_code == HTTPStatus.OK, response.text
|
||||
assert response.json()["data"]["id"] == clone["id"]
|
||||
|
||||
|
||||
def test_dashboard_v2_pin_limit(
|
||||
signoz: SigNoz,
|
||||
@@ -765,6 +787,12 @@ def test_dashboard_v2_pin_limit(
|
||||
)
|
||||
|
||||
|
||||
# TODO: add an integration test that clones an integration-source dashboard once
|
||||
# integration dashboards adopt the v2 (perses) flow. Today they're created via the
|
||||
# v1 path, and the v2 clone endpoint only operates on v6 dashboards — so the
|
||||
# integration-source branch of clone is unreachable through the API.
|
||||
|
||||
|
||||
# ─── LIKE escaping ───────────────────────────────────────────────────────────
|
||||
# Backslash is the LIKE escape character, declared explicitly via ESCAPE '\' on
|
||||
# every emitted LIKE/ILIKE. Postgres defaults to backslash; sqlite has no default
|
||||
|
||||