diff --git a/.codecov.yml b/.codecov.yml index 6e1b5b1c7ef12..02eeb89616cb2 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -82,6 +82,10 @@ coverage: target: 75 flags: - azure_iot_edge + BentoML: + target: 75 + flags: + - bentoml Boundary: target: 75 flags: @@ -884,6 +888,11 @@ flags: paths: - azure_iot_edge/datadog_checks/azure_iot_edge - azure_iot_edge/tests + bentoml: + carryforward: true + paths: + - bentoml/datadog_checks/bentoml + - bentoml/tests boundary: carryforward: true paths: diff --git a/.github/workflows/config/labeler.yml b/.github/workflows/config/labeler.yml index 4823b42d22d74..e675edf93aba5 100644 --- a/.github/workflows/config/labeler.yml +++ b/.github/workflows/config/labeler.yml @@ -87,6 +87,8 @@ integration/azure_active_directory: - azure_active_directory/**/* integration/azure_iot_edge: - azure_iot_edge/**/* +integration/bentoml: +- bentoml/**/* integration/beyondtrust_identity_security_insights: - beyondtrust_identity_security_insights/**/* integration/beyondtrust_password_safe: diff --git a/.github/workflows/test-all.yml b/.github/workflows/test-all.yml index 3460c9f513ddb..9496655a5ed95 100644 --- a/.github/workflows/test-all.yml +++ b/.github/workflows/test-all.yml @@ -420,6 +420,25 @@ jobs: minimum-base-package: ${{ inputs.minimum-base-package }} pytest-args: ${{ inputs.pytest-args }} secrets: inherit + j5a8a3b3: + uses: ./.github/workflows/test-target.yml + with: + job-name: BentoML + target: bentoml + platform: linux + runner: '["ubuntu-22.04"]' + repo: "${{ inputs.repo }}" + python-version: "${{ inputs.python-version }}" + latest: ${{ inputs.latest }} + agent-image: "${{ inputs.agent-image }}" + agent-image-py2: "${{ inputs.agent-image-py2 }}" + agent-image-windows: "${{ inputs.agent-image-windows }}" + agent-image-windows-py2: "${{ inputs.agent-image-windows-py2 }}" + test-py2: ${{ inputs.test-py2 }} + test-py3: ${{ inputs.test-py3 }} + minimum-base-package: ${{ inputs.minimum-base-package }} + pytest-args: ${{ inputs.pytest-args }} + secrets: inherit jfcf4b1a: uses: ./.github/workflows/test-target.yml with: diff --git a/bentoml/CHANGELOG.md b/bentoml/CHANGELOG.md new file mode 100644 index 0000000000000..7e1bd47b57012 --- /dev/null +++ b/bentoml/CHANGELOG.md @@ -0,0 +1,4 @@ +# CHANGELOG - BentoML + + + diff --git a/bentoml/README.md b/bentoml/README.md new file mode 100644 index 0000000000000..723dd7e68bdba --- /dev/null +++ b/bentoml/README.md @@ -0,0 +1,60 @@ +# Agent Check: BentoML + +## Overview + +This check monitors [BentoML][1] through the Datadog Agent. + +Include a high level overview of what this integration does: +- What does your product do (in 1-2 sentences)? +- What value will customers get from this integration, and why is it valuable to them? +- What specific data will your integration monitor, and what's the value of that data? + +## Setup + +Follow the instructions below to install and configure this check for an Agent running on a host. For containerized environments, see the [Autodiscovery Integration Templates][3] for guidance on applying these instructions. + +### Installation + +The BentoML check is included in the [Datadog Agent][2] package. +No additional installation is needed on your server. + +### Configuration + +1. Edit the `bentoml.d/conf.yaml` file, in the `conf.d/` folder at the root of your Agent's configuration directory to start collecting your bentoml performance data. See the [sample bentoml.d/conf.yaml][4] for all available configuration options. + +2. [Restart the Agent][5]. + +### Validation + +[Run the Agent's status subcommand][6] and look for `bentoml` under the Checks section. + +## Data Collected + +### Metrics + +See [metadata.csv][7] for a list of metrics provided by this integration. + +### Events + +The BentoML integration does not include any events. + +### Service Checks + +The BentoML integration does not include any service checks. + +See [service_checks.json][8] for a list of service checks provided by this integration. + +## Troubleshooting + +Need help? Contact [Datadog support][9]. + + +[1]: **LINK_TO_INTEGRATION_SITE** +[2]: https://app.datadoghq.com/account/settings/agent/latest +[3]: https://docs.datadoghq.com/containers/kubernetes/integrations/ +[4]: https://github.com/DataDog/integrations-core/blob/master/bentoml/datadog_checks/bentoml/data/conf.yaml.example +[5]: https://docs.datadoghq.com/agent/configuration/agent-commands/#start-stop-and-restart-the-agent +[6]: https://docs.datadoghq.com/agent/configuration/agent-commands/#agent-status-and-information +[7]: https://github.com/DataDog/integrations-core/blob/master/bentoml/metadata.csv +[8]: https://github.com/DataDog/integrations-core/blob/master/bentoml/assets/service_checks.json +[9]: https://docs.datadoghq.com/help/ diff --git a/bentoml/assets/configuration/spec.yaml b/bentoml/assets/configuration/spec.yaml new file mode 100644 index 0000000000000..31e9ce62e43d7 --- /dev/null +++ b/bentoml/assets/configuration/spec.yaml @@ -0,0 +1,15 @@ +name: BentoML +files: +- name: bentoml.yaml + options: + - template: init_config + options: + - template: init_config/openmetrics + - template: instances + options: + - template: instances/openmetrics + overrides: + openmetrics_endpoint.value.example: http://localhost:3000/metrics + openmetrics_endpoint.description: | + Endpoint exposing the BentoML Prometheus metrics. For more information refer to: + https://docs.bentoml.com/en/latest/build-with-bentoml/observability/metrics.html diff --git a/bentoml/assets/dashboards/placeholder.json b/bentoml/assets/dashboards/placeholder.json new file mode 100644 index 0000000000000..e0d6561275aeb --- /dev/null +++ b/bentoml/assets/dashboards/placeholder.json @@ -0,0 +1,8 @@ +{ + "author_name": "Datadog", + "description": null, + "layout_type": "ordered", + "template_variables": null, + "title": "Steven's Dashboard Thu, Jul 10, 3:44:27 pm", + "widgets": [] +} \ No newline at end of file diff --git a/bentoml/changelog.d/21232.added b/bentoml/changelog.d/21232.added new file mode 100644 index 0000000000000..fcd855853760f --- /dev/null +++ b/bentoml/changelog.d/21232.added @@ -0,0 +1,2 @@ +Add BentoML integration + diff --git a/bentoml/datadog_checks/bentoml/__about__.py b/bentoml/datadog_checks/bentoml/__about__.py new file mode 100644 index 0000000000000..1bde5986a04b2 --- /dev/null +++ b/bentoml/datadog_checks/bentoml/__about__.py @@ -0,0 +1,4 @@ +# (C) Datadog, Inc. 2025-present +# All rights reserved +# Licensed under a 3-clause BSD style license (see LICENSE) +__version__ = '0.0.1' diff --git a/bentoml/datadog_checks/bentoml/__init__.py b/bentoml/datadog_checks/bentoml/__init__.py new file mode 100644 index 0000000000000..2b1a982c7b4ce --- /dev/null +++ b/bentoml/datadog_checks/bentoml/__init__.py @@ -0,0 +1,7 @@ +# (C) Datadog, Inc. 2025-present +# All rights reserved +# Licensed under a 3-clause BSD style license (see LICENSE) +from .__about__ import __version__ +from .check import BentomlCheck + +__all__ = ['__version__', 'BentomlCheck'] diff --git a/bentoml/datadog_checks/bentoml/check.py b/bentoml/datadog_checks/bentoml/check.py new file mode 100644 index 0000000000000..2f71e81c55a0d --- /dev/null +++ b/bentoml/datadog_checks/bentoml/check.py @@ -0,0 +1,57 @@ +# (C) Datadog, Inc. 2025-present +# All rights reserved +# Licensed under a 3-clause BSD style license (see LICENSE) +from urllib.parse import urlparse, urlunparse + +from datadog_checks.base import OpenMetricsBaseCheckV2 +from datadog_checks.bentoml.metrics import ENDPOINT_METRICS, METRICS + + +class BentomlCheck(OpenMetricsBaseCheckV2): + __NAMESPACE__ = 'bentoml' + DEFAULT_METRIC_LIMIT = 0 + + def __init__(self, name, init_config, instances): + super(BentomlCheck, self).__init__(name, init_config, instances) + self.openmetrics_endpoint = self.instance.get('openmetrics_endpoint') + self.base_url = self._extract_base_url(self.openmetrics_endpoint) if self.openmetrics_endpoint else None + self.tags = self.instance.get('tags', []) + + def _extract_base_url(self, endpoint): + parsed = urlparse(endpoint) + path = parsed.path.rstrip('/') + base_path = path.rsplit('/', 1)[0] if '/' in path else '' + return urlunparse(parsed._replace(path=base_path or '/')) + + def get_default_config(self): + return { + 'openmetrics_endpoint': self.openmetrics_endpoint, + 'metrics': [METRICS], + } + + def check(self, instance): + super(BentomlCheck, self).check(instance) + if self.base_url: + self.check_health_endpoint() + + def check_health_endpoint(self): + for endpoint_path, metric_name in ENDPOINT_METRICS.items(): + try: + url = f"{self.base_url}{endpoint_path}" + response = self.http.get(url) + response.raise_for_status() + + tags = [*self.tags, f"status_code:{response.status_code}"] + self.gauge(metric_name, 1, tags=tags) + self.log.debug("Successfully checked %s at %s", metric_name, url) + except Exception as e: + status_code = None + if hasattr(e, 'response') and e.response is not None: + status_code = getattr(e.response, 'status_code', None) + + tags = [*self.tags] + if status_code is not None: + tags.append(f"status_code:{status_code}") + + self.log.debug("Failed to check %s at %s: %s", metric_name, url, str(e)) + self.gauge(metric_name, 0, tags=tags) diff --git a/bentoml/datadog_checks/bentoml/config_models/__init__.py b/bentoml/datadog_checks/bentoml/config_models/__init__.py new file mode 100644 index 0000000000000..4d80b1e478f62 --- /dev/null +++ b/bentoml/datadog_checks/bentoml/config_models/__init__.py @@ -0,0 +1,24 @@ +# (C) Datadog, Inc. 2025-present +# All rights reserved +# Licensed under a 3-clause BSD style license (see LICENSE) + +# This file is autogenerated. +# To change this file you should edit assets/configuration/spec.yaml and then run the following commands: +# ddev -x validate config -s +# ddev -x validate models -s + +from .instance import InstanceConfig +from .shared import SharedConfig + + +class ConfigMixin: + _config_model_instance: InstanceConfig + _config_model_shared: SharedConfig + + @property + def config(self) -> InstanceConfig: + return self._config_model_instance + + @property + def shared_config(self) -> SharedConfig: + return self._config_model_shared diff --git a/bentoml/datadog_checks/bentoml/config_models/defaults.py b/bentoml/datadog_checks/bentoml/config_models/defaults.py new file mode 100644 index 0000000000000..6e420ece4d70b --- /dev/null +++ b/bentoml/datadog_checks/bentoml/config_models/defaults.py @@ -0,0 +1,132 @@ +# (C) Datadog, Inc. 2025-present +# All rights reserved +# Licensed under a 3-clause BSD style license (see LICENSE) + +# This file is autogenerated. +# To change this file you should edit assets/configuration/spec.yaml and then run the following commands: +# ddev -x validate config -s +# ddev -x validate models -s + + +def shared_skip_proxy(): + return False + + +def shared_timeout(): + return 10 + + +def instance_allow_redirects(): + return True + + +def instance_auth_type(): + return 'basic' + + +def instance_cache_metric_wildcards(): + return True + + +def instance_cache_shared_labels(): + return True + + +def instance_collect_counters_with_distributions(): + return False + + +def instance_collect_histogram_buckets(): + return True + + +def instance_disable_generic_tags(): + return False + + +def instance_empty_default_hostname(): + return False + + +def instance_enable_health_service_check(): + return True + + +def instance_histogram_buckets_as_distributions(): + return False + + +def instance_ignore_connection_errors(): + return False + + +def instance_kerberos_auth(): + return 'disabled' + + +def instance_kerberos_delegate(): + return False + + +def instance_kerberos_force_initiate(): + return False + + +def instance_log_requests(): + return False + + +def instance_min_collection_interval(): + return 15 + + +def instance_non_cumulative_histogram_buckets(): + return False + + +def instance_persist_connections(): + return False + + +def instance_request_size(): + return 16 + + +def instance_skip_proxy(): + return False + + +def instance_tag_by_endpoint(): + return True + + +def instance_telemetry(): + return False + + +def instance_timeout(): + return 10 + + +def instance_tls_ignore_warning(): + return False + + +def instance_tls_use_host_header(): + return False + + +def instance_tls_verify(): + return True + + +def instance_use_latest_spec(): + return False + + +def instance_use_legacy_auth_encoding(): + return True + + +def instance_use_process_start_time(): + return False diff --git a/bentoml/datadog_checks/bentoml/config_models/instance.py b/bentoml/datadog_checks/bentoml/config_models/instance.py new file mode 100644 index 0000000000000..e33be37fd1cf5 --- /dev/null +++ b/bentoml/datadog_checks/bentoml/config_models/instance.py @@ -0,0 +1,172 @@ +# (C) Datadog, Inc. 2025-present +# All rights reserved +# Licensed under a 3-clause BSD style license (see LICENSE) + +# This file is autogenerated. +# To change this file you should edit assets/configuration/spec.yaml and then run the following commands: +# ddev -x validate config -s +# ddev -x validate models -s + +from __future__ import annotations + +from types import MappingProxyType +from typing import Any, Optional, Union + +from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator + +from datadog_checks.base.utils.functions import identity +from datadog_checks.base.utils.models import validation + +from . import defaults, validators + + +class AuthToken(BaseModel): + model_config = ConfigDict( + arbitrary_types_allowed=True, + frozen=True, + ) + reader: Optional[MappingProxyType[str, Any]] = None + writer: Optional[MappingProxyType[str, Any]] = None + + +class ExtraMetrics(BaseModel): + model_config = ConfigDict( + arbitrary_types_allowed=True, + extra='allow', + frozen=True, + ) + name: Optional[str] = None + type: Optional[str] = None + + +class MetricPatterns(BaseModel): + model_config = ConfigDict( + arbitrary_types_allowed=True, + frozen=True, + ) + exclude: Optional[tuple[str, ...]] = None + include: Optional[tuple[str, ...]] = None + + +class Metrics(BaseModel): + model_config = ConfigDict( + arbitrary_types_allowed=True, + extra='allow', + frozen=True, + ) + name: Optional[str] = None + type: Optional[str] = None + + +class Proxy(BaseModel): + model_config = ConfigDict( + arbitrary_types_allowed=True, + frozen=True, + ) + http: Optional[str] = None + https: Optional[str] = None + no_proxy: Optional[tuple[str, ...]] = None + + +class ShareLabels(BaseModel): + model_config = ConfigDict( + arbitrary_types_allowed=True, + frozen=True, + ) + labels: Optional[tuple[str, ...]] = None + match: Optional[tuple[str, ...]] = None + + +class InstanceConfig(BaseModel): + model_config = ConfigDict( + validate_default=True, + arbitrary_types_allowed=True, + frozen=True, + ) + allow_redirects: Optional[bool] = None + auth_token: Optional[AuthToken] = None + auth_type: Optional[str] = None + aws_host: Optional[str] = None + aws_region: Optional[str] = None + aws_service: Optional[str] = None + cache_metric_wildcards: Optional[bool] = None + cache_shared_labels: Optional[bool] = None + collect_counters_with_distributions: Optional[bool] = None + collect_histogram_buckets: Optional[bool] = None + connect_timeout: Optional[float] = None + disable_generic_tags: Optional[bool] = None + empty_default_hostname: Optional[bool] = None + enable_health_service_check: Optional[bool] = None + exclude_labels: Optional[tuple[str, ...]] = None + exclude_metrics: Optional[tuple[str, ...]] = None + exclude_metrics_by_labels: Optional[MappingProxyType[str, Union[bool, tuple[str, ...]]]] = None + extra_headers: Optional[MappingProxyType[str, Any]] = None + extra_metrics: Optional[tuple[Union[str, MappingProxyType[str, Union[str, ExtraMetrics]]], ...]] = None + headers: Optional[MappingProxyType[str, Any]] = None + histogram_buckets_as_distributions: Optional[bool] = None + hostname_format: Optional[str] = None + hostname_label: Optional[str] = None + ignore_connection_errors: Optional[bool] = None + ignore_tags: Optional[tuple[str, ...]] = None + include_labels: Optional[tuple[str, ...]] = None + kerberos_auth: Optional[str] = None + kerberos_cache: Optional[str] = None + kerberos_delegate: Optional[bool] = None + kerberos_force_initiate: Optional[bool] = None + kerberos_hostname: Optional[str] = None + kerberos_keytab: Optional[str] = None + kerberos_principal: Optional[str] = None + log_requests: Optional[bool] = None + metric_patterns: Optional[MetricPatterns] = None + metrics: Optional[tuple[Union[str, MappingProxyType[str, Union[str, Metrics]]], ...]] = None + min_collection_interval: Optional[float] = None + namespace: Optional[str] = Field(None, pattern='\\w*') + non_cumulative_histogram_buckets: Optional[bool] = None + ntlm_domain: Optional[str] = None + openmetrics_endpoint: str + password: Optional[str] = None + persist_connections: Optional[bool] = None + proxy: Optional[Proxy] = None + raw_line_filters: Optional[tuple[str, ...]] = None + raw_metric_prefix: Optional[str] = None + read_timeout: Optional[float] = None + rename_labels: Optional[MappingProxyType[str, Any]] = None + request_size: Optional[float] = None + service: Optional[str] = None + share_labels: Optional[MappingProxyType[str, Union[bool, ShareLabels]]] = None + skip_proxy: Optional[bool] = None + tag_by_endpoint: Optional[bool] = None + tags: Optional[tuple[str, ...]] = None + telemetry: Optional[bool] = None + timeout: Optional[float] = None + tls_ca_cert: Optional[str] = None + tls_cert: Optional[str] = None + tls_ciphers: Optional[tuple[str, ...]] = None + tls_ignore_warning: Optional[bool] = None + tls_private_key: Optional[str] = None + tls_protocols_allowed: Optional[tuple[str, ...]] = None + tls_use_host_header: Optional[bool] = None + tls_verify: Optional[bool] = None + use_latest_spec: Optional[bool] = None + use_legacy_auth_encoding: Optional[bool] = None + use_process_start_time: Optional[bool] = None + username: Optional[str] = None + + @model_validator(mode='before') + def _initial_validation(cls, values): + return validation.core.initialize_config(getattr(validators, 'initialize_instance', identity)(values)) + + @field_validator('*', mode='before') + def _validate(cls, value, info): + field = cls.model_fields[info.field_name] + field_name = field.alias or info.field_name + if field_name in info.context['configured_fields']: + value = getattr(validators, f'instance_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'instance_{info.field_name}', lambda: value)() + + return validation.utils.make_immutable(value) + + @model_validator(mode='after') + def _final_validation(cls, model): + return validation.core.check_model(getattr(validators, 'check_instance', identity)(model)) diff --git a/bentoml/datadog_checks/bentoml/config_models/shared.py b/bentoml/datadog_checks/bentoml/config_models/shared.py new file mode 100644 index 0000000000000..bd2982d6db33f --- /dev/null +++ b/bentoml/datadog_checks/bentoml/config_models/shared.py @@ -0,0 +1,60 @@ +# (C) Datadog, Inc. 2025-present +# All rights reserved +# Licensed under a 3-clause BSD style license (see LICENSE) + +# This file is autogenerated. +# To change this file you should edit assets/configuration/spec.yaml and then run the following commands: +# ddev -x validate config -s +# ddev -x validate models -s + +from __future__ import annotations + +from typing import Optional + +from pydantic import BaseModel, ConfigDict, field_validator, model_validator + +from datadog_checks.base.utils.functions import identity +from datadog_checks.base.utils.models import validation + +from . import defaults, validators + + +class Proxy(BaseModel): + model_config = ConfigDict( + arbitrary_types_allowed=True, + frozen=True, + ) + http: Optional[str] = None + https: Optional[str] = None + no_proxy: Optional[tuple[str, ...]] = None + + +class SharedConfig(BaseModel): + model_config = ConfigDict( + validate_default=True, + arbitrary_types_allowed=True, + frozen=True, + ) + proxy: Optional[Proxy] = None + service: Optional[str] = None + skip_proxy: Optional[bool] = None + timeout: Optional[float] = None + + @model_validator(mode='before') + def _initial_validation(cls, values): + return validation.core.initialize_config(getattr(validators, 'initialize_shared', identity)(values)) + + @field_validator('*', mode='before') + def _validate(cls, value, info): + field = cls.model_fields[info.field_name] + field_name = field.alias or info.field_name + if field_name in info.context['configured_fields']: + value = getattr(validators, f'shared_{info.field_name}', identity)(value, field=field) + else: + value = getattr(defaults, f'shared_{info.field_name}', lambda: value)() + + return validation.utils.make_immutable(value) + + @model_validator(mode='after') + def _final_validation(cls, model): + return validation.core.check_model(getattr(validators, 'check_shared', identity)(model)) diff --git a/bentoml/datadog_checks/bentoml/config_models/validators.py b/bentoml/datadog_checks/bentoml/config_models/validators.py new file mode 100644 index 0000000000000..8495a481e5308 --- /dev/null +++ b/bentoml/datadog_checks/bentoml/config_models/validators.py @@ -0,0 +1,13 @@ +# (C) Datadog, Inc. 2025-present +# All rights reserved +# Licensed under a 3-clause BSD style license (see LICENSE) + +# Here you can include additional config validators or transformers +# +# def initialize_instance(values, **kwargs): +# if 'my_option' not in values and 'my_legacy_option' in values: +# values['my_option'] = values['my_legacy_option'] +# if values.get('my_number') > 10: +# raise ValueError('my_number max value is 10, got %s' % str(values.get('my_number'))) +# +# return values diff --git a/bentoml/datadog_checks/bentoml/data/conf.yaml.example b/bentoml/datadog_checks/bentoml/data/conf.yaml.example new file mode 100644 index 0000000000000..20f5ee9e9f01e --- /dev/null +++ b/bentoml/datadog_checks/bentoml/data/conf.yaml.example @@ -0,0 +1,642 @@ +## All options defined here are available to all instances. +# +init_config: + + ## @param proxy - mapping - optional + ## Set HTTP or HTTPS proxies for all instances. Use the `no_proxy` list + ## to specify hosts that must bypass proxies. + ## + ## The SOCKS protocol is also supported like so: + ## + ## socks5://user:pass@host:port + ## + ## Using the scheme `socks5` causes the DNS resolution to happen on the + ## client, rather than on the proxy server. This is in line with `curl`, + ## which uses the scheme to decide whether to do the DNS resolution on + ## the client or proxy. If you want to resolve the domains on the proxy + ## server, use `socks5h` as the scheme. + # + # proxy: + # http: http://: + # https: https://: + # no_proxy: + # - + # - + + ## @param skip_proxy - boolean - optional - default: false + ## If set to `true`, this makes the check bypass any proxy + ## settings enabled and attempt to reach services directly. + # + # skip_proxy: false + + ## @param timeout - number - optional - default: 10 + ## The timeout for connecting to services. + # + # timeout: 10 + + ## @param service - string - optional + ## Attach the tag `service:` to every metric, event, and service check emitted by this integration. + ## + ## Additionally, this sets the default `service` for every log source. + # + # service: + +## Every instance is scheduled independently of the others. +# +instances: + + ## @param openmetrics_endpoint - string - required + ## Endpoint exposing the BentoML Prometheus metrics. For more information refer to: + ## https://docs.bentoml.com/en/latest/build-with-bentoml/observability/metrics.html + # + - openmetrics_endpoint: http://localhost:3000/metrics + + ## @param raw_metric_prefix - string - optional + ## A prefix that is removed from all exposed metric names, if present. + ## All configuration options will use the prefix-less name. + # + # raw_metric_prefix: _ + + ## @param extra_metrics - (list of string or mapping) - optional + ## This list defines metrics to collect from the `openmetrics_endpoint`, in addition to + ## what the check collects by default. If the check already collects a metric, then + ## metric definitions here take precedence. Metrics may be defined in 3 ways: + ## + ## 1. If the item is a string, then it represents the exposed metric name, and + ## the sent metric name will be identical. For example: + ## ``` + ## extra_metrics: + ## - + ## - + ## ``` + ## 2. If the item is a mapping, then the keys represent the exposed metric names. + ## + ## 1. If a value is a string, then it represents the sent metric name. For example: + ## ``` + ## extra_metrics: + ## - : + ## - : + ## ``` + ## 2. If a value is a mapping, then it must have a `name` and/or `type` key. + ## The `name` represents the sent metric name, and the `type` represents how + ## the metric should be handled, overriding any type information the endpoint + ## may provide. For example: + ## ``` + ## extra_metrics: + ## - : + ## name: + ## type: + ## - : + ## name: + ## type: + ## ``` + ## The supported native types are `gauge`, `counter`, `histogram`, and `summary`. + ## + ## Note: To collect counter metrics with names ending in `_total`, specify the metric name without the `_total` + ## suffix. For example, to collect the counter metric `promhttp_metric_handler_requests_total`, specify + ## `promhttp_metric_handler_requests`. This submits to Datadog the metric name appended with `.count`. + ## For more information, see: + ## https://github.com/OpenObservability/OpenMetrics/blob/main/specification/OpenMetrics.md#suffixes + ## + ## Regular expressions may be used to match the exposed metric names, for example: + ## ``` + ## extra_metrics: + ## - ^network_(ingress|egress)_.+ + ## - .+: + ## type: gauge + ## ``` + # + # extra_metrics: + # - + # - : + # - : + # name: + # type: + + ## @param exclude_metrics - list of strings - optional + ## A list of metrics to exclude, with each entry being either + ## the exact metric name or a regular expression. + ## In order to exclude all metrics but the ones matching a specific filter, + ## you can use a negative lookahead regex like: + ## - ^(?!foo).*$ + # + # exclude_metrics: [] + + ## @param exclude_metrics_by_labels - mapping - optional + ## A mapping of labels to exclude metrics with matching label name and their corresponding metric values. To match + ## all values of a label, set it to `true`. + ## + ## Note: Label filtering happens before `rename_labels`. + ## + ## For example, the following configuration instructs the check to exclude all metrics with + ## a label `worker` or a label `pid` with the value of either `23` or `42`. + ## + ## exclude_metrics_by_labels: + ## worker: true + ## pid: + ## - '23' + ## - '42' + # + # exclude_metrics_by_labels: {} + + ## @param exclude_labels - list of strings - optional + ## A list of labels to exclude, useful for high cardinality values like timestamps or UUIDs. + ## May be used in conjunction with `include_labels`. + ## Labels defined in `exclude_labels` will take precedence in case of overlap. + ## + ## Note: Label filtering happens before `rename_labels`. + # + # exclude_labels: [] + + ## @param include_labels - list of strings - optional + ## A list of labels to include. May be used in conjunction with `exclude_labels`. + ## Labels defined in `exclude_labels` will take precedence in case of overlap. + ## + ## Note: Label filtering happens before `rename_labels`. + # + # include_labels: [] + + ## @param rename_labels - mapping - optional + ## A mapping of label names to their new names. + # + # rename_labels: + # : + # : + + ## @param enable_health_service_check - boolean - optional - default: true + ## Whether or not to send a service check named `.openmetrics.health` which reports + ## the health of the `openmetrics_endpoint`. + # + # enable_health_service_check: true + + ## @param ignore_connection_errors - boolean - optional - default: false + ## Whether or not to ignore connection errors when scraping `openmetrics_endpoint`. + # + # ignore_connection_errors: false + + ## @param hostname_label - string - optional + ## Override the hostname for every metric submission with the value of one of its labels. + # + # hostname_label: + + ## @param hostname_format - string - optional + ## When `hostname_label` is set, this instructs the check how to format the values. The string + ## `` is replaced by the value of the label defined by `hostname_label`. + # + # hostname_format: + + ## @param collect_histogram_buckets - boolean - optional - default: true + ## Whether or not to send histogram buckets. + # + # collect_histogram_buckets: true + + ## @param non_cumulative_histogram_buckets - boolean - optional - default: false + ## Whether or not histogram buckets are non-cumulative and to come with a `lower_bound` tag. + # + # non_cumulative_histogram_buckets: false + + ## @param histogram_buckets_as_distributions - boolean - optional - default: false + ## Whether or not to send histogram buckets as Datadog distribution metrics. This implicitly + ## enables the `collect_histogram_buckets` and `non_cumulative_histogram_buckets` options. + ## + ## Learn more about distribution metrics: + ## https://docs.datadoghq.com/developers/metrics/types/?tab=distribution#metric-types + # + # histogram_buckets_as_distributions: false + + ## @param collect_counters_with_distributions - boolean - optional - default: false + ## Whether or not to also collect the observation counter metrics ending in `.sum` and `.count` + ## when sending histogram buckets as Datadog distribution metrics. This implicitly enables the + ## `histogram_buckets_as_distributions` option. + # + # collect_counters_with_distributions: false + + ## @param use_process_start_time - boolean - optional - default: false + ## Whether to enable a heuristic for reporting counter values on the first scrape. When true, + ## the first time an endpoint is scraped, check `process_start_time_seconds` to decide whether zero + ## initial value can be assumed for counters. This requires keeping metrics in memory until the entire + ## response is received. + # + # use_process_start_time: false + + ## @param share_labels - mapping - optional + ## This mapping allows for the sharing of labels across multiple metrics. The keys represent the + ## exposed metrics from which to share labels, and the values are mappings that configure the + ## sharing behavior. Each mapping must have at least one of the following keys: + ## + ## - labels - This is a list of labels to share. All labels are shared if this is not set. + ## - match - This is a list of labels to match on other metrics as a condition for sharing. + ## - values - This is a list of allowed values as a condition for sharing. + ## + ## To unconditionally share all labels of a metric, set it to `true`. + ## + ## For example, the following configuration instructs the check to apply all labels from `metric_a` + ## to all other metrics, the `node` label from `metric_b` to only those metrics that have a `pod` + ## label value that matches the `pod` label value of `metric_b`, and all labels from `metric_c` + ## to all other metrics if their value is equal to `23` or `42`. + # + # share_labels: + # metric_a: true + # metric_b: + # labels: + # - node + # match: + # - pod + # metric_c: + # values: + # - 23 + # - 42 + + ## @param cache_shared_labels - boolean - optional - default: true + ## When `share_labels` is set, it instructs the check to cache labels collected from the first payload + ## for improved performance. + ## + ## Set this to `false` to compute label sharing for every payload at the risk of potentially increased memory usage. + # + # cache_shared_labels: true + + ## @param raw_line_filters - list of strings - optional + ## A list of regular expressions used to exclude lines read from the `openmetrics_endpoint` + ## from being parsed. + # + # raw_line_filters: [] + + ## @param cache_metric_wildcards - boolean - optional - default: true + ## Whether or not to cache data from metrics that are defined by regular expressions rather + ## than the full metric name. + # + # cache_metric_wildcards: true + + ## @param telemetry - boolean - optional - default: false + ## Whether or not to submit metrics prefixed by `.telemetry.` for debugging purposes. + # + # telemetry: false + + ## @param ignore_tags - list of strings - optional + ## A list of regular expressions used to ignore tags added by Autodiscovery and entries in the `tags` option. + # + # ignore_tags: + # - + # - + # - + + ## @param proxy - mapping - optional + ## This overrides the `proxy` setting in `init_config`. + ## + ## Set HTTP or HTTPS proxies for this instance. Use the `no_proxy` list + ## to specify hosts that must bypass proxies. + ## + ## The SOCKS protocol is also supported, for example: + ## + ## socks5://user:pass@host:port + ## + ## Using the scheme `socks5` causes the DNS resolution to happen on the + ## client, rather than on the proxy server. This is in line with `curl`, + ## which uses the scheme to decide whether to do the DNS resolution on + ## the client or proxy. If you want to resolve the domains on the proxy + ## server, use `socks5h` as the scheme. + # + # proxy: + # http: http://: + # https: https://: + # no_proxy: + # - + # - + + ## @param skip_proxy - boolean - optional - default: false + ## This overrides the `skip_proxy` setting in `init_config`. + ## + ## If set to `true`, this makes the check bypass any proxy + ## settings enabled and attempt to reach services directly. + # + # skip_proxy: false + + ## @param auth_type - string - optional - default: basic + ## The type of authentication to use. The available types (and related options) are: + ## ``` + ## - basic + ## |__ username + ## |__ password + ## |__ use_legacy_auth_encoding + ## - digest + ## |__ username + ## |__ password + ## - ntlm + ## |__ ntlm_domain + ## |__ password + ## - kerberos + ## |__ kerberos_auth + ## |__ kerberos_cache + ## |__ kerberos_delegate + ## |__ kerberos_force_initiate + ## |__ kerberos_hostname + ## |__ kerberos_keytab + ## |__ kerberos_principal + ## - aws + ## |__ aws_region + ## |__ aws_host + ## |__ aws_service + ## ``` + ## The `aws` auth type relies on boto3 to automatically gather AWS credentials, for example: from `.aws/credentials`. + ## Details: https://boto3.amazonaws.com/v1/documentation/api/latest/guide/configuration.html#configuring-credentials + # + # auth_type: basic + + ## @param use_legacy_auth_encoding - boolean - optional - default: true + ## When `auth_type` is set to `basic`, this determines whether to encode as `latin1` rather than `utf-8`. + # + # use_legacy_auth_encoding: true + + ## @param username - string - optional + ## The username to use if services are behind basic or digest auth. + # + # username: + + ## @param password - string - optional + ## The password to use if services are behind basic or NTLM auth. + # + # password: + + ## @param ntlm_domain - string - optional + ## If your services use NTLM authentication, specify + ## the domain used in the check. For NTLM Auth, append + ## the username to domain, not as the `username` parameter. + # + # ntlm_domain: \ + + ## @param kerberos_auth - string - optional - default: disabled + ## If your services use Kerberos authentication, you can specify the Kerberos + ## strategy to use between: + ## + ## - required + ## - optional + ## - disabled + ## + ## See https://github.com/requests/requests-kerberos#mutual-authentication + # + # kerberos_auth: disabled + + ## @param kerberos_cache - string - optional + ## Sets the KRB5CCNAME environment variable. + ## It should point to a credential cache with a valid TGT. + # + # kerberos_cache: + + ## @param kerberos_delegate - boolean - optional - default: false + ## Set to `true` to enable Kerberos delegation of credentials to a server that requests delegation. + ## + ## See https://github.com/requests/requests-kerberos#delegation + # + # kerberos_delegate: false + + ## @param kerberos_force_initiate - boolean - optional - default: false + ## Set to `true` to preemptively initiate the Kerberos GSS exchange and + ## present a Kerberos ticket on the initial request (and all subsequent). + ## + ## See https://github.com/requests/requests-kerberos#preemptive-authentication + # + # kerberos_force_initiate: false + + ## @param kerberos_hostname - string - optional + ## Override the hostname used for the Kerberos GSS exchange if its DNS name doesn't + ## match its Kerberos hostname, for example: behind a content switch or load balancer. + ## + ## See https://github.com/requests/requests-kerberos#hostname-override + # + # kerberos_hostname: + + ## @param kerberos_principal - string - optional + ## Set an explicit principal, to force Kerberos to look for a + ## matching credential cache for the named user. + ## + ## See https://github.com/requests/requests-kerberos#explicit-principal + # + # kerberos_principal: + + ## @param kerberos_keytab - string - optional + ## Set the path to your Kerberos key tab file. + # + # kerberos_keytab: + + ## @param auth_token - mapping - optional + ## This allows for the use of authentication information from dynamic sources. + ## Both a reader and writer must be configured. + ## + ## The available readers are: + ## + ## - type: file + ## path (required): The absolute path for the file to read from. + ## pattern: A regular expression pattern with a single capture group used to find the + ## token rather than using the entire file, for example: Your secret is (.+) + ## - type: oauth + ## url (required): The token endpoint. + ## client_id (required): The client identifier. + ## client_secret (required): The client secret. + ## basic_auth: Whether the provider expects credentials to be transmitted in + ## an HTTP Basic Auth header. The default is: false + ## options: Mapping of additional options to pass to the provider, such as the audience + ## or the scope. For example: + ## options: + ## audience: https://example.com + ## scope: read:example + ## + ## The available writers are: + ## + ## - type: header + ## name (required): The name of the field, for example: Authorization + ## value: The template value, for example `Bearer `. The default is: + ## placeholder: The substring in `value` to replace with the token, defaults to: + # + # auth_token: + # reader: + # type: + # : + # : + # writer: + # type: + # : + # : + + ## @param aws_region - string - optional + ## If your services require AWS Signature Version 4 signing, set the region. + ## + ## See https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html + # + # aws_region: + + ## @param aws_host - string - optional + ## If your services require AWS Signature Version 4 signing, set the host. + ## This only needs the hostname and does not require the protocol (HTTP, HTTPS, and more). + ## For example, if connecting to https://us-east-1.amazonaws.com/, set `aws_host` to `us-east-1.amazonaws.com`. + ## + ## Note: This setting is not necessary for official integrations. + ## + ## See https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html + # + # aws_host: + + ## @param aws_service - string - optional + ## If your services require AWS Signature Version 4 signing, set the service code. For a list + ## of available service codes, see https://docs.aws.amazon.com/general/latest/gr/rande.html + ## + ## Note: This setting is not necessary for official integrations. + ## + ## See https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html + # + # aws_service: + + ## @param tls_verify - boolean - optional - default: true + ## Instructs the check to validate the TLS certificate of services. + # + # tls_verify: true + + ## @param tls_use_host_header - boolean - optional - default: false + ## If a `Host` header is set, this enables its use for SNI (matching against the TLS certificate CN or SAN). + # + # tls_use_host_header: false + + ## @param tls_ignore_warning - boolean - optional - default: false + ## If `tls_verify` is disabled, security warnings are logged by the check. + ## Disable those by setting `tls_ignore_warning` to true. + # + # tls_ignore_warning: false + + ## @param tls_cert - string - optional + ## The path to a single file in PEM format containing a certificate as well as any + ## number of CA certificates needed to establish the certificate's authenticity for + ## use when connecting to services. It may also contain an unencrypted private key to use. + # + # tls_cert: + + ## @param tls_private_key - string - optional + ## The unencrypted private key to use for `tls_cert` when connecting to services. This is + ## required if `tls_cert` is set and it does not already contain a private key. + # + # tls_private_key: + + ## @param tls_ca_cert - string - optional + ## The path to a file of concatenated CA certificates in PEM format or a directory + ## containing several CA certificates in PEM format. If a directory, the directory + ## must have been processed using the `openssl rehash` command. See: + ## https://www.openssl.org/docs/man3.2/man1/c_rehash.html + # + # tls_ca_cert: + + ## @param tls_protocols_allowed - list of strings - optional + ## The expected versions of TLS/SSL when fetching intermediate certificates. + ## Only `SSLv3`, `TLSv1.2`, `TLSv1.3` are allowed by default. The possible values are: + ## SSLv3 + ## TLSv1 + ## TLSv1.1 + ## TLSv1.2 + ## TLSv1.3 + # + # tls_protocols_allowed: + # - SSLv3 + # - TLSv1.2 + # - TLSv1.3 + + ## @param tls_ciphers - list of strings - optional + ## The list of ciphers suites to use when connecting to an endpoint. If not specified, + ## `ALL` ciphers are used. For list of ciphers see: + ## https://www.openssl.org/docs/man1.0.2/man1/ciphers.html + # + # tls_ciphers: + # - TLS_AES_256_GCM_SHA384 + # - TLS_CHACHA20_POLY1305_SHA256 + # - TLS_AES_128_GCM_SHA256 + + ## @param headers - mapping - optional + ## The headers parameter allows you to send specific headers with every request. + ## You can use it for explicitly specifying the host header or adding headers for + ## authorization purposes. + ## + ## This overrides any default headers. + # + # headers: + # Host: + # X-Auth-Token: + + ## @param extra_headers - mapping - optional + ## Additional headers to send with every request. + # + # extra_headers: + # Host: + # X-Auth-Token: + + ## @param timeout - number - optional - default: 10 + ## The timeout for accessing services. + ## + ## This overrides the `timeout` setting in `init_config`. + # + # timeout: 10 + + ## @param connect_timeout - number - optional + ## The connect timeout for accessing services. Defaults to `timeout`. + # + # connect_timeout: + + ## @param read_timeout - number - optional + ## The read timeout for accessing services. Defaults to `timeout`. + # + # read_timeout: + + ## @param request_size - number - optional - default: 16 + ## The number of kibibytes (KiB) to read from streaming HTTP responses at a time. + # + # request_size: 16 + + ## @param log_requests - boolean - optional - default: false + ## Whether or not to debug log the HTTP(S) requests made, including the method and URL. + # + # log_requests: false + + ## @param persist_connections - boolean - optional - default: false + ## Whether or not to persist cookies and use connection pooling for improved performance. + # + # persist_connections: false + + ## @param allow_redirects - boolean - optional - default: true + ## Whether or not to allow URL redirection. + # + # allow_redirects: true + + ## @param tags - list of strings - optional + ## A list of tags to attach to every metric and service check emitted by this instance. + ## + ## Learn more about tagging at https://docs.datadoghq.com/tagging + # + # tags: + # - : + # - : + + ## @param service - string - optional + ## Attach the tag `service:` to every metric, event, and service check emitted by this integration. + ## + ## Overrides any `service` defined in the `init_config` section. + # + # service: + + ## @param min_collection_interval - number - optional - default: 15 + ## This changes the collection interval of the check. For more information, see: + ## https://docs.datadoghq.com/developers/write_agent_check/#collection-interval + # + # min_collection_interval: 15 + + ## @param empty_default_hostname - boolean - optional - default: false + ## This forces the check to send metrics with no hostname. + ## + ## This is useful for cluster-level checks. + # + # empty_default_hostname: false + + ## @param metric_patterns - mapping - optional + ## A mapping of metrics to include or exclude, with each entry being a regular expression. + ## + ## Metrics defined in `exclude` will take precedence in case of overlap. + # + # metric_patterns: + # include: + # - + # exclude: + # - diff --git a/bentoml/datadog_checks/bentoml/metrics.py b/bentoml/datadog_checks/bentoml/metrics.py new file mode 100644 index 0000000000000..997ec4f9849f4 --- /dev/null +++ b/bentoml/datadog_checks/bentoml/metrics.py @@ -0,0 +1,19 @@ +# (C) Datadog, Inc. 2025-present +# All rights reserved +# Licensed under a 3-clause BSD style license (see LICENSE) + +METRICS = { + "bentoml_service_request_in_progress": "service.request.in_progress", + "bentoml_service_request": "service.request", + "bentoml_service_request_duration_seconds": "service.request.duration", + "bentoml_service_adaptive_batch_size": "service.adaptive_batch_size", + "bentoml_service_last_request_timestamp_seconds": { + "type": "time_elapsed", + "name": "service.time_since_last_request", + }, +} + +ENDPOINT_METRICS = { + "/livez": "endpoint_livez", + "/readyz": "endpoint_readyz", +} diff --git a/bentoml/hatch.toml b/bentoml/hatch.toml new file mode 100644 index 0000000000000..c85c5f07a7df2 --- /dev/null +++ b/bentoml/hatch.toml @@ -0,0 +1,4 @@ +[env.collectors.datadog-checks] + +[[envs.default.matrix]] +python = ["3.12"] diff --git a/bentoml/manifest.json b/bentoml/manifest.json new file mode 100644 index 0000000000000..1deb29c329786 --- /dev/null +++ b/bentoml/manifest.json @@ -0,0 +1,52 @@ +{ + "manifest_version": "2.0.0", + "app_uuid": "2163f7af-7c30-4583-ab15-892d980227e9", + "app_id": "bentoml", + "display_on_public_website": false, + "tile": { + "overview": "README.md#Overview", + "configuration": "README.md#Setup", + "support": "README.md#Support", + "changelog": "CHANGELOG.md", + "description": "BentoML is an open-source framework for ML model deployment. This integration collects BentoML service metrics.", + "title": "BentoML", + "media": [], + "classifier_tags": [ + "Supported OS::Linux", + "Supported OS::Windows", + "Supported OS::macOS", + "Submitted Data Type::Metrics", + "Offering::Integration", + "Category::AI/ML" + ] + }, + "assets": { + "integration": { + "auto_install": true, + "source_type_id": 55717919, + "source_type_name": "BentoML", + "configuration": { + "spec": "assets/configuration/spec.yaml" + }, + "events": { + "creates_events": false + }, + "metrics": { + "prefix": "bentoml.", + "check": "bentoml.service.request.count", + "metadata_path": "metadata.csv" + } + }, + "dashboards": { + "BentoML Placeholder": "assets/dashboards/placeholder.json" + }, + "monitors": {}, + "saved_views": {} + }, + "author": { + "support_email": "help@datadoghq.com", + "name": "Datadog", + "homepage": "https://www.datadoghq.com", + "sales_email": "info@datadoghq.com" + } +} diff --git a/bentoml/metadata.csv b/bentoml/metadata.csv new file mode 100644 index 0000000000000..3189c5e82e0a2 --- /dev/null +++ b/bentoml/metadata.csv @@ -0,0 +1,12 @@ +metric_name,metric_type,interval,unit_name,per_unit_name,description,orientation,integration,short_name,curated_metric,sample_tags +bentoml.endpoint_livez,gauge,,,,,0,bentoml,,, +bentoml.endpoint_readyz,gauge,,,,,0,bentoml,,, +bentoml.service.adaptive_batch_size.bucket,count,,,,,0,bentoml,,, +bentoml.service.adaptive_batch_size.count,count,,,,,0,bentoml,,, +bentoml.service.adaptive_batch_size.sum,count,,,,,0,bentoml,,, +bentoml.service.request.count,count,,,,,0,bentoml,,, +bentoml.service.request.duration.bucket,count,,,,,0,bentoml,,, +bentoml.service.request.duration.count,count,,,,,0,bentoml,,, +bentoml.service.request.duration.sum,count,,,,,0,bentoml,,, +bentoml.service.request.in_progress,gauge,,,,,0,bentoml,,, +bentoml.service.time_since_last_request,gauge,,,,,0,bentoml,,, diff --git a/bentoml/pyproject.toml b/bentoml/pyproject.toml new file mode 100644 index 0000000000000..1a8a67788bce6 --- /dev/null +++ b/bentoml/pyproject.toml @@ -0,0 +1,60 @@ +[build-system] +requires = [ + "hatchling>=0.13.0", +] +build-backend = "hatchling.build" + +[project] +name = "datadog-bentoml" +description = "The BentoML check" +readme = "README.md" +license = "BSD-3-Clause" +requires-python = ">=3.12" +keywords = [ + "datadog", + "datadog agent", + "datadog check", + "bentoml", +] +authors = [ + { name = "Datadog", email = "packages@datadoghq.com" }, +] +classifiers = [ + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "Intended Audience :: System Administrators", + "License :: OSI Approved :: BSD License", + "Private :: Do Not Upload", + "Programming Language :: Python :: 3.12", + "Topic :: System :: Monitoring", +] +dependencies = [ + "datadog-checks-base>=37.16.0", +] +dynamic = [ + "version", +] + +[project.optional-dependencies] +deps = [] + +[project.urls] +Source = "https://github.com/DataDog/integrations-core" + +[tool.hatch.version] +path = "datadog_checks/bentoml/__about__.py" + +[tool.hatch.build.targets.sdist] +include = [ + "/datadog_checks", + "/tests", + "/manifest.json", +] + +[tool.hatch.build.targets.wheel] +include = [ + "/datadog_checks/bentoml", +] +dev-mode-dirs = [ + ".", +] diff --git a/bentoml/tests/__init__.py b/bentoml/tests/__init__.py new file mode 100644 index 0000000000000..c9f1f2a9882c7 --- /dev/null +++ b/bentoml/tests/__init__.py @@ -0,0 +1,3 @@ +# (C) Datadog, Inc. 2025-present +# All rights reserved +# Licensed under a 3-clause BSD style license (see LICENSE) diff --git a/bentoml/tests/common.py b/bentoml/tests/common.py new file mode 100644 index 0000000000000..6bad50b3a310e --- /dev/null +++ b/bentoml/tests/common.py @@ -0,0 +1,36 @@ +# (C) Datadog, Inc. 2025-present +# All rights reserved +# Licensed under a 3-clause BSD style license (see LICENSE) +import os + +from datadog_checks.dev import get_here + +HERE = get_here() + +OM_MOCKED_INSTANCE = { + 'openmetrics_endpoint': 'http://bentoml:3000/metrics', + 'tags': ['test:tag'], +} + + +def get_fixture_path(filename): + return os.path.join(HERE, 'fixtures', filename) + + +METRICS = [ + 'bentoml.service.request.in_progress', + 'bentoml.service.request.count', + 'bentoml.service.request.duration.count', + 'bentoml.service.request.duration.sum', + 'bentoml.service.request.duration.bucket', + 'bentoml.service.adaptive_batch_size.count', + 'bentoml.service.adaptive_batch_size.sum', + 'bentoml.service.adaptive_batch_size.bucket', + 'bentoml.service.request.in_progress', + 'bentoml.service.time_since_last_request', +] + +ENDPOINT_METRICS = [ + 'bentoml.endpoint_livez', + 'bentoml.endpoint_readyz', +] diff --git a/bentoml/tests/conftest.py b/bentoml/tests/conftest.py new file mode 100644 index 0000000000000..1423666ef6381 --- /dev/null +++ b/bentoml/tests/conftest.py @@ -0,0 +1,14 @@ +# (C) Datadog, Inc. 2025-present +# All rights reserved +# Licensed under a 3-clause BSD style license (see LICENSE) +import pytest + + +@pytest.fixture(scope='session') +def dd_environment(): + yield + + +@pytest.fixture +def instance(): + return {} diff --git a/bentoml/tests/fixtures/metrics.txt b/bentoml/tests/fixtures/metrics.txt new file mode 100644 index 0000000000000..e1ac99ec32f4e --- /dev/null +++ b/bentoml/tests/fixtures/metrics.txt @@ -0,0 +1,248 @@ +# HELP bentoml_service_request_total Total number of runner RPC +# TYPE bentoml_service_request_total counter +bentoml_service_request_total{endpoint="/summarize",http_response_code="200",runner_name="Summarization",service_name="Summarization",service_version="not available"} 5.0 +bentoml_service_request_total{endpoint="/summarize",http_response_code="500",runner_name="Summarization",service_name="Summarization",service_version="not available"} 0.0 +bentoml_service_request_total{endpoint="/",http_response_code="200",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_total{endpoint="/static_content/swagger-initializer.js",http_response_code="200",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_total{endpoint="/static_content/index.css",http_response_code="200",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_total{endpoint="/static_content/swagger-ui.css",http_response_code="200",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_total{endpoint="/static_content/swagger-ui-standalone-preset.js",http_response_code="200",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_total{endpoint="/static_content/swagger-ui-bundle.js",http_response_code="200",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_total{endpoint="/docs.json",http_response_code="200",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_total{endpoint="/static_content/favicon-dark-32x32.png",http_response_code="200",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_total{endpoint="/summarize",http_response_code="400",runner_name="Summarization",service_name="Summarization",service_version="not available"} 4.0 +bentoml_service_request_total{endpoint="/static_content/favicon-dark-32x32.png",http_response_code="304",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +# HELP bentoml_service_request_duration_seconds runner RPC duration in seconds +# TYPE bentoml_service_request_duration_seconds histogram +bentoml_service_request_duration_seconds_sum{endpoint="/",http_response_code="200",runner_name="Summarization",service_name="Summarization",service_version="not available"} 0.021970166999381036 +bentoml_service_request_duration_seconds_sum{endpoint="/static_content/swagger-initializer.js",http_response_code="200",runner_name="Summarization",service_name="Summarization",service_version="not available"} 0.005407916993135586 +bentoml_service_request_duration_seconds_sum{endpoint="/static_content/index.css",http_response_code="200",runner_name="Summarization",service_name="Summarization",service_version="not available"} 0.006735666000167839 +bentoml_service_request_duration_seconds_sum{endpoint="/static_content/swagger-ui.css",http_response_code="200",runner_name="Summarization",service_name="Summarization",service_version="not available"} 0.011091499996837229 +bentoml_service_request_duration_seconds_sum{endpoint="/static_content/swagger-ui-standalone-preset.js",http_response_code="200",runner_name="Summarization",service_name="Summarization",service_version="not available"} 0.012548540995339863 +bentoml_service_request_duration_seconds_sum{endpoint="/static_content/swagger-ui-bundle.js",http_response_code="200",runner_name="Summarization",service_name="Summarization",service_version="not available"} 0.033470624999608845 +bentoml_service_request_duration_seconds_sum{endpoint="/docs.json",http_response_code="200",runner_name="Summarization",service_name="Summarization",service_version="not available"} 0.02028170900302939 +bentoml_service_request_duration_seconds_sum{endpoint="/static_content/favicon-dark-32x32.png",http_response_code="200",runner_name="Summarization",service_name="Summarization",service_version="not available"} 0.0024089159996947274 +bentoml_service_request_duration_seconds_sum{endpoint="/summarize",http_response_code="200",runner_name="Summarization",service_name="Summarization",service_version="not available"} 12.333088291998138 +bentoml_service_request_duration_seconds_sum{endpoint="/summarize",http_response_code="400",runner_name="Summarization",service_name="Summarization",service_version="not available"} 0.008715959003893659 +bentoml_service_request_duration_seconds_sum{endpoint="/static_content/favicon-dark-32x32.png",http_response_code="304",runner_name="Summarization",service_name="Summarization",service_version="not available"} 0.00413187500089407 +bentoml_service_request_duration_seconds_bucket{endpoint="/",http_response_code="200",le="0.005",runner_name="Summarization",service_name="Summarization",service_version="not available"} 0.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/",http_response_code="200",le="0.01",runner_name="Summarization",service_name="Summarization",service_version="not available"} 0.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/",http_response_code="200",le="0.025",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/",http_response_code="200",le="0.05",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/",http_response_code="200",le="0.1",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/",http_response_code="200",le="0.25",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/",http_response_code="200",le="0.5",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/",http_response_code="200",le="1.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/",http_response_code="200",le="2.5",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/",http_response_code="200",le="5.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/",http_response_code="200",le="10.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/",http_response_code="200",le="30.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/",http_response_code="200",le="60.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/",http_response_code="200",le="120.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/",http_response_code="200",le="180.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/",http_response_code="200",le="+Inf",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_count{endpoint="/",http_response_code="200",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-initializer.js",http_response_code="200",le="0.005",runner_name="Summarization",service_name="Summarization",service_version="not available"} 0.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-initializer.js",http_response_code="200",le="0.01",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-initializer.js",http_response_code="200",le="0.025",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-initializer.js",http_response_code="200",le="0.05",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-initializer.js",http_response_code="200",le="0.1",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-initializer.js",http_response_code="200",le="0.25",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-initializer.js",http_response_code="200",le="0.5",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-initializer.js",http_response_code="200",le="1.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-initializer.js",http_response_code="200",le="2.5",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-initializer.js",http_response_code="200",le="5.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-initializer.js",http_response_code="200",le="10.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-initializer.js",http_response_code="200",le="30.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-initializer.js",http_response_code="200",le="60.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-initializer.js",http_response_code="200",le="120.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-initializer.js",http_response_code="200",le="180.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-initializer.js",http_response_code="200",le="+Inf",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_count{endpoint="/static_content/swagger-initializer.js",http_response_code="200",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/index.css",http_response_code="200",le="0.005",runner_name="Summarization",service_name="Summarization",service_version="not available"} 0.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/index.css",http_response_code="200",le="0.01",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/index.css",http_response_code="200",le="0.025",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/index.css",http_response_code="200",le="0.05",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/index.css",http_response_code="200",le="0.1",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/index.css",http_response_code="200",le="0.25",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/index.css",http_response_code="200",le="0.5",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/index.css",http_response_code="200",le="1.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/index.css",http_response_code="200",le="2.5",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/index.css",http_response_code="200",le="5.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/index.css",http_response_code="200",le="10.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/index.css",http_response_code="200",le="30.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/index.css",http_response_code="200",le="60.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/index.css",http_response_code="200",le="120.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/index.css",http_response_code="200",le="180.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/index.css",http_response_code="200",le="+Inf",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_count{endpoint="/static_content/index.css",http_response_code="200",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-ui.css",http_response_code="200",le="0.005",runner_name="Summarization",service_name="Summarization",service_version="not available"} 0.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-ui.css",http_response_code="200",le="0.01",runner_name="Summarization",service_name="Summarization",service_version="not available"} 0.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-ui.css",http_response_code="200",le="0.025",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-ui.css",http_response_code="200",le="0.05",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-ui.css",http_response_code="200",le="0.1",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-ui.css",http_response_code="200",le="0.25",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-ui.css",http_response_code="200",le="0.5",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-ui.css",http_response_code="200",le="1.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-ui.css",http_response_code="200",le="2.5",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-ui.css",http_response_code="200",le="5.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-ui.css",http_response_code="200",le="10.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-ui.css",http_response_code="200",le="30.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-ui.css",http_response_code="200",le="60.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-ui.css",http_response_code="200",le="120.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-ui.css",http_response_code="200",le="180.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-ui.css",http_response_code="200",le="+Inf",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_count{endpoint="/static_content/swagger-ui.css",http_response_code="200",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-ui-standalone-preset.js",http_response_code="200",le="0.005",runner_name="Summarization",service_name="Summarization",service_version="not available"} 0.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-ui-standalone-preset.js",http_response_code="200",le="0.01",runner_name="Summarization",service_name="Summarization",service_version="not available"} 0.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-ui-standalone-preset.js",http_response_code="200",le="0.025",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-ui-standalone-preset.js",http_response_code="200",le="0.05",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-ui-standalone-preset.js",http_response_code="200",le="0.1",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-ui-standalone-preset.js",http_response_code="200",le="0.25",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-ui-standalone-preset.js",http_response_code="200",le="0.5",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-ui-standalone-preset.js",http_response_code="200",le="1.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-ui-standalone-preset.js",http_response_code="200",le="2.5",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-ui-standalone-preset.js",http_response_code="200",le="5.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-ui-standalone-preset.js",http_response_code="200",le="10.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-ui-standalone-preset.js",http_response_code="200",le="30.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-ui-standalone-preset.js",http_response_code="200",le="60.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-ui-standalone-preset.js",http_response_code="200",le="120.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-ui-standalone-preset.js",http_response_code="200",le="180.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-ui-standalone-preset.js",http_response_code="200",le="+Inf",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_count{endpoint="/static_content/swagger-ui-standalone-preset.js",http_response_code="200",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-ui-bundle.js",http_response_code="200",le="0.005",runner_name="Summarization",service_name="Summarization",service_version="not available"} 0.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-ui-bundle.js",http_response_code="200",le="0.01",runner_name="Summarization",service_name="Summarization",service_version="not available"} 0.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-ui-bundle.js",http_response_code="200",le="0.025",runner_name="Summarization",service_name="Summarization",service_version="not available"} 0.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-ui-bundle.js",http_response_code="200",le="0.05",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-ui-bundle.js",http_response_code="200",le="0.1",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-ui-bundle.js",http_response_code="200",le="0.25",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-ui-bundle.js",http_response_code="200",le="0.5",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-ui-bundle.js",http_response_code="200",le="1.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-ui-bundle.js",http_response_code="200",le="2.5",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-ui-bundle.js",http_response_code="200",le="5.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-ui-bundle.js",http_response_code="200",le="10.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-ui-bundle.js",http_response_code="200",le="30.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-ui-bundle.js",http_response_code="200",le="60.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-ui-bundle.js",http_response_code="200",le="120.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-ui-bundle.js",http_response_code="200",le="180.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/swagger-ui-bundle.js",http_response_code="200",le="+Inf",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_count{endpoint="/static_content/swagger-ui-bundle.js",http_response_code="200",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/docs.json",http_response_code="200",le="0.005",runner_name="Summarization",service_name="Summarization",service_version="not available"} 0.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/docs.json",http_response_code="200",le="0.01",runner_name="Summarization",service_name="Summarization",service_version="not available"} 0.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/docs.json",http_response_code="200",le="0.025",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/docs.json",http_response_code="200",le="0.05",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/docs.json",http_response_code="200",le="0.1",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/docs.json",http_response_code="200",le="0.25",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/docs.json",http_response_code="200",le="0.5",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/docs.json",http_response_code="200",le="1.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/docs.json",http_response_code="200",le="2.5",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/docs.json",http_response_code="200",le="5.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/docs.json",http_response_code="200",le="10.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/docs.json",http_response_code="200",le="30.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/docs.json",http_response_code="200",le="60.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/docs.json",http_response_code="200",le="120.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/docs.json",http_response_code="200",le="180.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/docs.json",http_response_code="200",le="+Inf",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_count{endpoint="/docs.json",http_response_code="200",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/favicon-dark-32x32.png",http_response_code="200",le="0.005",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/favicon-dark-32x32.png",http_response_code="200",le="0.01",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/favicon-dark-32x32.png",http_response_code="200",le="0.025",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/favicon-dark-32x32.png",http_response_code="200",le="0.05",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/favicon-dark-32x32.png",http_response_code="200",le="0.1",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/favicon-dark-32x32.png",http_response_code="200",le="0.25",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/favicon-dark-32x32.png",http_response_code="200",le="0.5",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/favicon-dark-32x32.png",http_response_code="200",le="1.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/favicon-dark-32x32.png",http_response_code="200",le="2.5",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/favicon-dark-32x32.png",http_response_code="200",le="5.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/favicon-dark-32x32.png",http_response_code="200",le="10.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/favicon-dark-32x32.png",http_response_code="200",le="30.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/favicon-dark-32x32.png",http_response_code="200",le="60.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/favicon-dark-32x32.png",http_response_code="200",le="120.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/favicon-dark-32x32.png",http_response_code="200",le="180.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/favicon-dark-32x32.png",http_response_code="200",le="+Inf",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_count{endpoint="/static_content/favicon-dark-32x32.png",http_response_code="200",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/summarize",http_response_code="200",le="0.005",runner_name="Summarization",service_name="Summarization",service_version="not available"} 0.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/summarize",http_response_code="200",le="0.01",runner_name="Summarization",service_name="Summarization",service_version="not available"} 0.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/summarize",http_response_code="200",le="0.025",runner_name="Summarization",service_name="Summarization",service_version="not available"} 0.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/summarize",http_response_code="200",le="0.05",runner_name="Summarization",service_name="Summarization",service_version="not available"} 0.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/summarize",http_response_code="200",le="0.1",runner_name="Summarization",service_name="Summarization",service_version="not available"} 0.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/summarize",http_response_code="200",le="0.25",runner_name="Summarization",service_name="Summarization",service_version="not available"} 0.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/summarize",http_response_code="200",le="0.5",runner_name="Summarization",service_name="Summarization",service_version="not available"} 0.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/summarize",http_response_code="200",le="1.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 0.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/summarize",http_response_code="200",le="2.5",runner_name="Summarization",service_name="Summarization",service_version="not available"} 4.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/summarize",http_response_code="200",le="5.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 5.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/summarize",http_response_code="200",le="10.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 5.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/summarize",http_response_code="200",le="30.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 5.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/summarize",http_response_code="200",le="60.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 5.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/summarize",http_response_code="200",le="120.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 5.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/summarize",http_response_code="200",le="180.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 5.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/summarize",http_response_code="200",le="+Inf",runner_name="Summarization",service_name="Summarization",service_version="not available"} 5.0 +bentoml_service_request_duration_seconds_count{endpoint="/summarize",http_response_code="200",runner_name="Summarization",service_name="Summarization",service_version="not available"} 5.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/summarize",http_response_code="400",le="0.005",runner_name="Summarization",service_name="Summarization",service_version="not available"} 4.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/summarize",http_response_code="400",le="0.01",runner_name="Summarization",service_name="Summarization",service_version="not available"} 4.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/summarize",http_response_code="400",le="0.025",runner_name="Summarization",service_name="Summarization",service_version="not available"} 4.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/summarize",http_response_code="400",le="0.05",runner_name="Summarization",service_name="Summarization",service_version="not available"} 4.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/summarize",http_response_code="400",le="0.1",runner_name="Summarization",service_name="Summarization",service_version="not available"} 4.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/summarize",http_response_code="400",le="0.25",runner_name="Summarization",service_name="Summarization",service_version="not available"} 4.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/summarize",http_response_code="400",le="0.5",runner_name="Summarization",service_name="Summarization",service_version="not available"} 4.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/summarize",http_response_code="400",le="1.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 4.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/summarize",http_response_code="400",le="2.5",runner_name="Summarization",service_name="Summarization",service_version="not available"} 4.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/summarize",http_response_code="400",le="5.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 4.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/summarize",http_response_code="400",le="10.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 4.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/summarize",http_response_code="400",le="30.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 4.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/summarize",http_response_code="400",le="60.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 4.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/summarize",http_response_code="400",le="120.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 4.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/summarize",http_response_code="400",le="180.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 4.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/summarize",http_response_code="400",le="+Inf",runner_name="Summarization",service_name="Summarization",service_version="not available"} 4.0 +bentoml_service_request_duration_seconds_count{endpoint="/summarize",http_response_code="400",runner_name="Summarization",service_name="Summarization",service_version="not available"} 4.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/favicon-dark-32x32.png",http_response_code="304",le="0.005",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/favicon-dark-32x32.png",http_response_code="304",le="0.01",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/favicon-dark-32x32.png",http_response_code="304",le="0.025",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/favicon-dark-32x32.png",http_response_code="304",le="0.05",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/favicon-dark-32x32.png",http_response_code="304",le="0.1",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/favicon-dark-32x32.png",http_response_code="304",le="0.25",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/favicon-dark-32x32.png",http_response_code="304",le="0.5",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/favicon-dark-32x32.png",http_response_code="304",le="1.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/favicon-dark-32x32.png",http_response_code="304",le="2.5",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/favicon-dark-32x32.png",http_response_code="304",le="5.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/favicon-dark-32x32.png",http_response_code="304",le="10.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/favicon-dark-32x32.png",http_response_code="304",le="30.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/favicon-dark-32x32.png",http_response_code="304",le="60.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/favicon-dark-32x32.png",http_response_code="304",le="120.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/favicon-dark-32x32.png",http_response_code="304",le="180.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_bucket{endpoint="/static_content/favicon-dark-32x32.png",http_response_code="304",le="+Inf",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_request_duration_seconds_count{endpoint="/static_content/favicon-dark-32x32.png",http_response_code="304",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +# HELP bentoml_service_last_request_timestamp_seconds Timestamp of the last received request +# TYPE bentoml_service_last_request_timestamp_seconds gauge +bentoml_service_last_request_timestamp_seconds{pid="37104",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.7568634726216471e+09 +# HELP bentoml_service_request_in_progress Total number of runner RPC in progress now +# TYPE bentoml_service_request_in_progress gauge +bentoml_service_request_in_progress{endpoint="/",runner_name="Summarization",service_name="Summarization",service_version="not available"} 0.0 +bentoml_service_request_in_progress{endpoint="/static_content/swagger-ui.css",runner_name="Summarization",service_name="Summarization",service_version="not available"} 0.0 +bentoml_service_request_in_progress{endpoint="/static_content/swagger-ui-bundle.js",runner_name="Summarization",service_name="Summarization",service_version="not available"} 0.0 +bentoml_service_request_in_progress{endpoint="/static_content/swagger-ui-standalone-preset.js",runner_name="Summarization",service_name="Summarization",service_version="not available"} 0.0 +bentoml_service_request_in_progress{endpoint="/static_content/index.css",runner_name="Summarization",service_name="Summarization",service_version="not available"} 0.0 +bentoml_service_request_in_progress{endpoint="/static_content/swagger-initializer.js",runner_name="Summarization",service_name="Summarization",service_version="not available"} 0.0 +bentoml_service_request_in_progress{endpoint="/docs.json",runner_name="Summarization",service_name="Summarization",service_version="not available"} 0.0 +bentoml_service_request_in_progress{endpoint="/static_content/favicon-dark-32x32.png",runner_name="Summarization",service_name="Summarization",service_version="not available"} 0.0 +bentoml_service_request_in_progress{endpoint="/summarize",runner_name="Summarization",service_name="Summarization",service_version="not available"} 0.0 +# HELP bentoml_service_adaptive_batch_size Made up Adaptive Batch Size +# TYPE bentoml_service_adaptive_batch_size histogram +bentoml_service_adaptive_batch_size_sum{endpoint="/",http_response_code="200",runner_name="Summarization",service_name="Summarization",service_version="not available"} 0.021970166999381036 +bentoml_service_adaptive_batch_size_bucket{endpoint="/",http_response_code="200",le="0.005",runner_name="Summarization",service_name="Summarization",service_version="not available"} 0.0 +bentoml_service_adaptive_batch_size_bucket{endpoint="/",http_response_code="200",le="0.01",runner_name="Summarization",service_name="Summarization",service_version="not available"} 0.0 +bentoml_service_adaptive_batch_size_bucket{endpoint="/",http_response_code="200",le="0.025",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_adaptive_batch_size_bucket{endpoint="/",http_response_code="200",le="0.05",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_adaptive_batch_size_bucket{endpoint="/",http_response_code="200",le="0.1",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_adaptive_batch_size_bucket{endpoint="/",http_response_code="200",le="0.25",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_adaptive_batch_size_bucket{endpoint="/",http_response_code="200",le="0.5",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_adaptive_batch_size_bucket{endpoint="/",http_response_code="200",le="1.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_adaptive_batch_size_bucket{endpoint="/",http_response_code="200",le="2.5",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_adaptive_batch_size_bucket{endpoint="/",http_response_code="200",le="5.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_adaptive_batch_size_bucket{endpoint="/",http_response_code="200",le="10.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_adaptive_batch_size_bucket{endpoint="/",http_response_code="200",le="30.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_adaptive_batch_size_bucket{endpoint="/",http_response_code="200",le="60.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_adaptive_batch_size_bucket{endpoint="/",http_response_code="200",le="120.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_adaptive_batch_size_bucket{endpoint="/",http_response_code="200",le="180.0",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_adaptive_batch_size_bucket{endpoint="/",http_response_code="200",le="+Inf",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 +bentoml_service_adaptive_batch_size_count{endpoint="/",http_response_code="200",runner_name="Summarization",service_name="Summarization",service_version="not available"} 1.0 \ No newline at end of file diff --git a/bentoml/tests/test_unit.py b/bentoml/tests/test_unit.py new file mode 100644 index 0000000000000..37b4ea1a1c0eb --- /dev/null +++ b/bentoml/tests/test_unit.py @@ -0,0 +1,72 @@ +# (C) Datadog, Inc. 2025-present +# All rights reserved +# Licensed under a 3-clause BSD style license (see LICENSE) +from unittest.mock import Mock, patch + +import pytest +import requests + +from datadog_checks.base.constants import ServiceCheck +from datadog_checks.bentoml import BentomlCheck +from datadog_checks.dev.utils import get_metadata_metrics + +from .common import ( + ENDPOINT_METRICS, + METRICS, + OM_MOCKED_INSTANCE, + get_fixture_path, +) + + +def test_bentoml_mock_metrics(dd_run_check, aggregator, mock_http_response): + mock_http_response(file_path=get_fixture_path('metrics.txt')) + + with patch('datadog_checks.bentoml.check.BentomlCheck.http') as mock_http: + mock_response = type('MockResponse', (), {'status_code': 200})() + mock_http.get.return_value = mock_response + mock_http.get.return_value.raise_for_status = lambda: None + + check = BentomlCheck('bentoml', {}, [OM_MOCKED_INSTANCE]) + dd_run_check(check) + + for metric in METRICS: + aggregator.assert_metric(metric) + + for metric in ENDPOINT_METRICS: + aggregator.assert_metric(metric, value=1, tags=['test:tag', 'status_code:200']) + + aggregator.assert_all_metrics_covered() + assert mock_http.get.call_count == 2 + aggregator.assert_metrics_using_metadata(get_metadata_metrics()) + aggregator.assert_all_metrics_covered() + aggregator.assert_service_check('bentoml.openmetrics.health', ServiceCheck.OK) + + +def test_bentoml_mock_invalid_endpoint(dd_run_check, aggregator, mock_http_response): + mock_http_response(status_code=503) + check = BentomlCheck('bentoml', {}, [OM_MOCKED_INSTANCE]) + with pytest.raises(Exception): + dd_run_check(check) + + aggregator.assert_service_check('bentoml.openmetrics.health', ServiceCheck.CRITICAL) + + +def test_bentoml_mock_valid_endpoint_invalid_health(dd_run_check, aggregator, mock_http_response): + mock_http_response(file_path=get_fixture_path('metrics.txt')) + + _err = Mock() + _err.status_code = 500 + _http_err = requests.HTTPError("500 Internal Server Error") + _http_err.response = _err + _err.raise_for_status.side_effect = _http_err + + with patch('datadog_checks.bentoml.check.BentomlCheck.http') as mock_http: + mock_http.get.return_value = _err + + check = BentomlCheck('bentoml', {}, [OM_MOCKED_INSTANCE]) + dd_run_check(check) + + for metric in ENDPOINT_METRICS: + aggregator.assert_metric(metric, value=0, tags=['test:tag', 'status_code:500']) + + aggregator.assert_service_check('bentoml.openmetrics.health', ServiceCheck.OK) diff --git a/sqlserver/tests/test_unit.py b/sqlserver/tests/test_unit.py index 5ac018e3a75db..1bb0c039d15fc 100644 --- a/sqlserver/tests/test_unit.py +++ b/sqlserver/tests/test_unit.py @@ -867,21 +867,6 @@ def test_fetch_throws(instance_docker): schemas._fetch_schema_data("dummy_cursor", time.time(), "my_db") -def test_submit_is_called_if_too_many_columns(instance_docker): - check = SQLServer(CHECK_NAME, {}, [instance_docker]) - schemas = Schemas(check, check._config) - with ( - mock.patch('time.time', side_effect=[0, 0]), - mock.patch('datadog_checks.sqlserver.schemas.Schemas._query_schema_information', return_value={"id": 1}), - mock.patch('datadog_checks.sqlserver.schemas.Schemas._get_tables', return_value=[1, 2]), - mock.patch('datadog_checks.sqlserver.schemas.SubmitData.submit') as mocked_submit, - mock.patch('datadog_checks.sqlserver.schemas.Schemas._get_tables_data', return_value=(1000_000, {"id": 1})), - ): - with pytest.raises(StopIteration): - schemas._fetch_schema_data("dummy_cursor", time.time(), "my_db") - mocked_submit.called_once() - - def test_exception_handling_by_do_for_dbs(instance_docker): check = SQLServer(CHECK_NAME, {}, [instance_docker]) check.initialize_connection()