Preview
We're still working on this feature, but we'd love for you to try it out!
This feature is currently provided as part of a preview pursuant to our pre-release policies.
New Relic now empowers your team to monitor your Microsoft SQL Server database performance using New Relic Distribution of OpenTelemetry (NRDOT) with New Relic's database monitoring capabilities. This integration provides comprehensive insights into database metrics, query performance, and system health using the NRDOT collector.
This NRDOT-based approach complements our existing On-Host Integration (OHI) by leveraging OpenTelemetry standards for database monitoring, making it easier to integrate with your existing observability stack.
Prerequisites
Before you begin, ensure you have the following:
Valid New Relic license key
Supported database versions: SQL Server 2017 or later
SQL Server database setup:
- Administrative access to your SQL Server instance (
sysadminrole or equivalent) - Microsoft SQL Server that supports on-premises managed instances
- Network connectivity between the NRDOT collector and your SQL Server
- SQL Server Management Studio (SSMS) or
sqlcmdutility - Server hostname or IP address
- Port number (usually 1433) or custom port
- Windows domain or SQL Server authentication
- SSL preference
- Administrative access to your SQL Server instance (
System requirements:
- Windows or Linux system to run the NRDOT collector
- Network connectivity to New Relic's OTLP endpoint
Set-up the NRDOT Collector for Microsoft SQL Server monitoring
You can use the NRDOT collector to monitor your Microsoft SQL Server databases. The NRDOT collector is a pre-configured distribution that includes New Relic-specific components.
To install & configure the NRDOT Collector, follow these steps:
Setup the NRDOT Collector
Install the collector based on your operating system and architecture.
Importante
It is recommended to install the NRDOT Collector on the same host as your SQL Server instance to view infra-level metrics for query performance monitoring.
Configure database user
Run the following script as a root user/sysadmin to create the newrelic monitoring user and grant global read permissions.
Configure NRDOT Collector
Replace your config.yaml with the below content:
Windows:
C:\Program Files (x86)\NRDOT Collector Host\config.yamlLinux:
/etc/nrdot-collector-host/config.yamlImportante
If you're an existing NRDOT Collector user, ensure to merge the above configuration with your existing
config.yamlfile. This includes adding the new receivers, processors, and exporters for MSSQL Database monitoring while retaining your current configurations.
# NRDOT Collector Configuration for New Relic SQL Server Integration# SQL Server On-Premises/VM Configuration
extensions: health_check:
receivers: otlp: protocols: grpc: http:
hostmetrics: # Default collection interval is 60s. Lower if you need finer granularity. collection_interval: 60s scrapers: cpu: metrics: system.cpu.time: enabled: false system.cpu.utilization: enabled: true load: memory: metrics: system.memory.utilization: enabled: true paging: metrics: system.paging.utilization: enabled: false system.paging.faults: enabled: false filesystem: metrics: system.filesystem.utilization: enabled: true disk: metrics: system.disk.merged: enabled: false system.disk.pending_operations: enabled: false system.disk.weighted_io_time: enabled: false network: metrics: system.network.connections: enabled: false # Uncomment to enable process metrics, which can be noisy but valuable. # processes: # process: # metrics: # process.cpu.utilization: # enabled: true # process.cpu.time: # enabled: false
filelog: include: - /var/log/alternatives.log - /var/log/cloud-init.log - /var/log/auth.log - /var/log/dpkg.log - /var/log/syslog - /var/log/messages - /var/log/secure - /var/log/yum.log
newrelicsqlserver: hostname: "<YOUR_DB_HOST>" port: "<YOUR_DB_PORT>" username: "<USERNAME>" password: "<PASSWORD>" monitored_databases: [] # timeout: 30s # collection_interval: 30s # query_monitoring_fetch_interval: 15 # query_monitoring_response_time_threshold: 100 # query_monitoring_count_threshold: 30 # interval_calculator_cache_ttl_minutes: 10
# Core Metric Category Toggles - Enable/disable entire categories of metrics # enable_instance_metrics: true # enable_database_metrics: true # enable_user_connection_metrics: true # enable_wait_time_metrics: true # enable_failover_cluster_metrics: true # enable_database_principals_metrics: true # enable_database_role_membership_metrics: true # enable_security_metrics: true # enable_lock_metrics: true # enable_thread_pool_metrics: true # enable_tempdb_metrics: true # enable_database_buffer_metrics: true
processors: # group system.cpu metrics by cpu metricstransform: transforms: - include: system.cpu.utilization action: update operations: - action: aggregate_labels label_set: [ state ] aggregation_type: mean - include: system.paging.operations action: update operations: - action: aggregate_labels label_set: [ direction ] aggregation_type: sum
# remove system.cpu metrics for states filter/exclude_cpu_utilization: metrics: datapoint: - 'metric.name == "system.cpu.utilization" and attributes["state"] == "interrupt"' - 'metric.name == "system.cpu.utilization" and attributes["state"] == "nice"' - 'metric.name == "system.cpu.utilization" and attributes["state"] == "softirq"'
filter/exclude_memory_utilization: metrics: datapoint: - 'metric.name == "system.memory.utilization" and attributes["state"] == "slab_unreclaimable"' - 'metric.name == "system.memory.utilization" and attributes["state"] == "inactive"' - 'metric.name == "system.memory.utilization" and attributes["state"] == "cached"' - 'metric.name == "system.memory.utilization" and attributes["state"] == "buffered"' - 'metric.name == "system.memory.utilization" and attributes["state"] == "slab_reclaimable"'
filter/exclude_memory_usage: metrics: datapoint: - 'metric.name == "system.memory.usage" and attributes["state"] == "slab_unreclaimable"' - 'metric.name == "system.memory.usage" and attributes["state"] == "inactive"'
filter/exclude_filesystem_utilization: metrics: datapoint: - 'metric.name == "system.filesystem.utilization" and attributes["type"] == "squashfs"'
filter/exclude_filesystem_usage: metrics: datapoint: - 'metric.name == "system.filesystem.usage" and attributes["type"] == "squashfs"' - 'metric.name == "system.filesystem.usage" and attributes["state"] == "reserved"'
filter/exclude_filesystem_inodes_usage: metrics: datapoint: - 'metric.name == "system.filesystem.inodes.usage" and attributes["type"] == "squashfs"' - 'metric.name == "system.filesystem.inodes.usage" and attributes["state"] == "reserved"'
filter/exclude_system_disk: metrics: datapoint: - 'metric.name == "system.disk.operations" and IsMatch(attributes["device"], "^loop.*") == true' - 'metric.name == "system.disk.merged" and IsMatch(attributes["device"], "^loop.*") == true' - 'metric.name == "system.disk.io" and IsMatch(attributes["device"], "^loop.*") == true' - 'metric.name == "system.disk.io_time" and IsMatch(attributes["device"], "^loop.*") == true' - 'metric.name == "system.disk.operation_time" and IsMatch(attributes["device"], "^loop.*") == true'
filter/exclude_system_paging: metrics: datapoint: - 'metric.name == "system.paging.usage" and attributes["state"] == "cached"' - 'metric.name == "system.paging.operations" and attributes["type"] == "cached"'
filter/exclude_network: metrics: datapoint: - 'IsMatch(metric.name, "^system.network.*") == true and attributes["device"] == "lo"'
attributes/exclude_system_paging: include: match_type: strict metric_names: - system.paging.operations actions: - key: type action: delete
# Transform to clear description and unit fields transform/clear_metadata: metric_statements: - context: metric statements: - set(metric.description, "") - set(metric.unit, "")
# Filter to only include execution plan and event metrics (for logs conversion) filter/exec_plan_include: metrics: include: match_type: strict metric_names: - sqlserver.slowquery.query_details - sqlserver.execution.plan - sqlserver.blocking_query.details - sqlserver.activequery.query_details
# Filter to exclude execution plan and event metrics (from main metrics pipeline) filter/exec_plan_exclude: metrics: exclude: match_type: strict metric_names: - sqlserver.slowquery.query_details - sqlserver.execution.plan - sqlserver.blocking_query.details - sqlserver.activequery.query_details
cumulativetodelta: max_staleness: 5m include: match_type: strict metrics: # Wait stats (sys.dm_os_wait_stats) - sqlserver.wait_stats.latch.wait_time_ms - sqlserver.wait_stats.latch.waiting_tasks_count - sqlserver.wait_stats.wait_time_ms - sqlserver.wait_stats.waiting_tasks_count # Instance stats (sys.dm_os_performance_counters) - sqlserver.stats.sql_compilations_per_sec - sqlserver.stats.sql_recompilations_per_sec - sqlserver.stats.lock_waits_per_sec - sqlserver.stats.deadlocks_per_sec - sqlserver.stats.user_errors_per_sec - sqlserver.stats.kill_connection_errors_per_sec - sqlserver.access.page_splits_per_sec - sqlserver.buffer.checkpoint_pages_per_sec - sqlserver.bufferpool.batch_requests_per_sec - sqlserver.instance.transactions_per_sec - sqlserver.instance.forced_parameterizations_per_sec - sqlserver.instance.full_scans_rate - sqlserver.instance.lock_timeouts_rate # Database log (sys.dm_os_performance_counters) - sqlserver.database.log.flushes_per_sec - sqlserver.database.log.bytes_flushed_per_sec - sqlserver.database.log.flush_waits_per_sec # Failover cluster - sqlserver.failover_cluster.log_bytes_received_per_sec # User connections - sqlserver.user_connections.authentication.logins_per_sec
deltatorate: metrics: - sqlserver.wait_stats.latch.wait_time_ms - sqlserver.wait_stats.latch.waiting_tasks_count - sqlserver.wait_stats.wait_time_ms - sqlserver.wait_stats.waiting_tasks_count - sqlserver.stats.sql_compilations_per_sec - sqlserver.stats.sql_recompilations_per_sec - sqlserver.stats.lock_waits_per_sec - sqlserver.stats.deadlocks_per_sec - sqlserver.stats.user_errors_per_sec - sqlserver.stats.kill_connection_errors_per_sec - sqlserver.access.page_splits_per_sec - sqlserver.buffer.checkpoint_pages_per_sec - sqlserver.bufferpool.batch_requests_per_sec - sqlserver.instance.transactions_per_sec - sqlserver.instance.forced_parameterizations_per_sec - sqlserver.instance.full_scans_rate - sqlserver.instance.lock_timeouts_rate - sqlserver.database.log.flushes_per_sec - sqlserver.database.log.bytes_flushed_per_sec - sqlserver.database.log.flush_waits_per_sec - sqlserver.failover_cluster.log_bytes_received_per_sec - sqlserver.user_connections.authentication.logins_per_sec
transform/host: metric_statements: - context: metric statements: - set(metric.description, "") - set(metric.unit, "")
transform: trace_statements: - context: span statements: - truncate_all(span.attributes, 4095) - truncate_all(resource.attributes, 4095) log_statements: - context: log statements: - truncate_all(log.attributes, 4095) - truncate_all(resource.attributes, 4095)
# used to prevent out of memory situations on the collector memory_limiter: check_interval: 1s limit_mib: ${env:NEW_RELIC_MEMORY_LIMIT_MIB:-100}
batch:
resourcedetection: detectors: ["system"] system: hostname_sources: ["os"] resource_attributes: host.id: enabled: true
resourcedetection/db_safe: detectors: ["system"] override: false system: hostname_sources: ["os"] resource_attributes: host.id: enabled: true
resourcedetection/cloud: detectors: ["gcp", "ec2", "azure"] timeout: 2s override: true
resourcedetection/env: detectors: ["env"] timeout: 2s override: true
connectors: metricsaslogs: include_resource_attributes: true include_scope_info: true
exporters: otlphttp: endpoint: "<YOUR_NEWRELIC_OTLP_ENDPOINT>" headers: api-key: "<YOUR_NEWRELIC_API_KEY>" compression: gzip
service: pipelines: metrics/host: receivers: [hostmetrics] processors: - memory_limiter - metricstransform - filter/exclude_cpu_utilization - filter/exclude_memory_utilization - filter/exclude_memory_usage - filter/exclude_filesystem_utilization - filter/exclude_filesystem_usage - filter/exclude_filesystem_inodes_usage - filter/exclude_system_disk - filter/exclude_network - attributes/exclude_system_paging - transform/host - resourcedetection - resourcedetection/cloud - resourcedetection/db_safe - resourcedetection/env - cumulativetodelta - deltatorate - batch exporters: [otlphttp] traces: receivers: [otlp] processors: [memory_limiter, transform, resourcedetection, resourcedetection/cloud, resourcedetection/env, batch] exporters: [otlphttp] metrics: receivers: [newrelicsqlserver, otlp] processors: [memory_limiter, transform, resourcedetection, resourcedetection/cloud, resourcedetection/env, filter/exec_plan_exclude, batch] exporters: [otlphttp] logs: receivers: [metricsaslogs, otlp] processors: [memory_limiter, transform, resourcedetection, resourcedetection/cloud, resourcedetection/env, batch] exporters: [otlphttp] metrics/exec_plan_to_logs: receivers: [newrelicsqlserver, otlp] processors: [memory_limiter, transform, resourcedetection, resourcedetection/cloud, resourcedetection/env, filter/exec_plan_include, batch] exporters: [metricsaslogs] extensions: [health_check]Configuration parameters
The following table describes the key configuration parameters for the newrelicsqlserver receiver:
Parameter | Description |
|---|---|
| Enter your SQL Server hostname or IP address |
| Enter your SQL Server port number. The default value is set to 1433. |
| Enter your database username for authentication |
| Enter your database password for authentication |
| Enter the New Relic OTLP endpoint. For more information, refer to New Relic OTLP endpoints documentation. |
| Enter your New Relic API key. |
| Minimum response time in milliseconds to consider a query as slow. The default value is set to |
| Minimum execution count to include a query in monitoring. The default value is set to |
| Interval in seconds to fetch query monitoring data. The default value is set to |
| Interval in seconds to collect metrics. The default value is set to |
Importante
If you enable core metric category toggles and notice data gaps, increase both the timeout and collection_interval to give scrapers more time to complete. Always keep the timeout value less than the collection_interval to prevent overlapping scrape cycles.
collection_interval: 60stimeout: 45s # must be < collection_intervalquery_monitoring_fetch_interval: 30Restart NRDOT collector
After updating your configuration, restart the NRDOT collector service:
For Windows, to restart the NRDOT Collector service, run:
bash$net stop nrdot-collector-host$net start nrdot-collector-hostFor Linux, to restart the NRDOT Collector service, run:
bash$sudo systemctl restart nrdot-collector-host
Dica
Always restart the NRDOT collector service after making configuration changes to ensure the new settings take effect.
(Optional) Set up APM-database correlation
To correlate your application performance with database operations, you can set up database service identification. This feature allows you to see exactly which applications are generating specific database workloads. For more information, refer to set up database service identification to get APM-database correlation in New Relic.
Importante
To view database performance data in APM, both entities must be in the same New Relic account. If the entities are in different New Relic accounts, you must have access to both accounts to view the data.
(Optional) Configure secret management
The secret management feature allows you to securely manage sensitive information, such as database credentials. This helps to enhance the security of your monitoring setup by avoiding hardcoding sensitive data in configuration files. For more information, refer to secret management.
Find and use your data
Once your data is being collected, you can access comprehensive SQL Server database monitoring through New Relic's UI.
To find your SQL Server database entity in New Relic:
- Go to https://one.newrelic.com > All Capabilities > Databases.
- Set the search criteria as
instrumentation.provider = opentelemetry. - Select your SQL Server database from the list of entities.
NRDOT collector supported commands
To manage the NRDOT Collector service, view logs, or check the status of the service, use the following available commands based on your operating system.
Troubleshooting
If you encounter any network connectivity issues with the NRDOT Collector, run the following commands to test connectivity to your SQL Server instance on port 1433:
For Windows, run:
bash$Test-NetConnection -ComputerName <YOUR_IP_ADDRESS> -Port <YOUR_PORT_NUMBER>For Linux, run:
bash$nc -zv <YOUR_IP_ADDRESS> <YOUR_PORT_NUMBER>
Available metrics
Monitor your SQL Server database performance with metrics organized by configuration flags. Default metrics are collected automatically for New Relic UI functionality. You can also use provided additional metrics to gain advanced and deeper insights when you enable specific scrapers.
Default metrics
These metrics are essential for New Relic's SQL Server monitoring features and are collected automatically regardless of your configuration.
Additional metrics
Enable these additional metrics as required for deeper insights into your SQL Server database performance and health.
What's next
After setting up SQL Server database monitoring with NRDOT:
- Create custom dashboards to visualize your database metrics
- Set up alerts for critical database performance thresholds
- Explore your data using New Relic's query capabilities