Lambda metrics
Introduction
Lambdas can collect metrics the same way as any service, see service metrics. This metrics can be collected by Prometheus via /lambda_metrics path.
To enable metrics collection:
Prometheus service must be launched and configured to collect metrics from /lambda_metrics
LUNA_LAMBDA_METRICS_SETTINGS.origin must be set to actual Prometheus address.
LUNA_SERVICE_METRICS settings must be enabled
Lambda metrics can be received via luna-lambda service via /lambdas/<lambdaId>/metrics resource. Response format follows Prometheus HTTP Api.
User metrics
Lambda can be provided with custom set of metrics, that later can be collected by Prometheus.
To add metrics to lambda they must be instanced im module scope of lambda_main.py file:
from luna_lambda_tools.public.metrics.user_metrics import Counter, Gauge, Histogram, Summary
USER_SUM = Summary("user_sum", description="sum", labelNames=["custom_label"])
USER_HISTOGRAM = Histogram("user_histo", description="histogram", labelNames=["custom_label"])
USER_COUNTER = Counter("user_counter", description="counter")
USER_GAUGE = Gauge("user_gauge", description="gauge")
USER_METRICS = [
USER_GAUGE,
USER_SUM,
USER_HISTOGRAM,
USER_COUNTER,
]
Later this metrics can be used to collect data:
...
USER_SUM.observe(0.5, labels={"custom_label": "value"})
USER_HISTOGRAM.observe(0.6, labels={"custom_label": "value1"})
USER_COUNTER.inc(1.0)
USER_GAUGE.set(2.3)
- Available metrics:
Counter - Used for monotonically increasing values — things that only go up.
USER_COUNTER.inc() # Increment by 1 USER_COUNTER.inc(3) # Increment by 3
Gauge - Used for values that go up and down.
USER_GAUGE.set(100) # Set to 100 USER_GAUGE.inc() # Increment by 1 USER_GAUGE.inc(3) # Increment by 3 USER_GAUGE.dec(2) # Decrement by 2
Summary - Used to track event durations or sizes.
USER_SUM.observe(0.5) # Observes 0.5
Histogram - Used to measure distributions.
USER_HISTOGRAM.observe(0.5) # Observes 0.5
After collection by prometheus each metric will be stored as subset of metrics following this pattern:
Metric Type |
Example Metric Name |
Prometheus-Exposed Metrics |
|---|---|---|
Counter |
|
|
Gauge |
|
|
Summary |
|
|
Histogram |
|
|
This metrics can be collected via /lambdas/<lambdaId>/metrics resource.
Note: LUNA_LAMBDA_METRICS_SETTINGS.enabled must be set to true, otherwise metrics data won`t be collected.
Here is an example of standalone lambda that mesures execution time on /main route and periodically tracks lambda cpu load:
requirements.txtpsutillambda_main.pyimport asyncio import time import psutil from luna_lambda_tools import StandaloneLambdaRequest, logger from luna_lambda_tools.public.metrics.user_metrics import Gauge, Summary LAMBDA_REQUEST_DURATION = Summary("lambda_request_duration", description="Request duration") CPU_STATS = Gauge("cpu_stats", description="Lambda cpu load") USER_METRICS = [CPU_STATS, LAMBDA_REQUEST_DURATION] class UserCtx: def __init__(self): self.cpuStatsCollectorTask = None async def onStart(self): self.cpuStatsCollectorTask = asyncio.create_task(self._collectCpuStats()) async def onShutdown(self): self.cpuStatsCollectorTask.cancel() @staticmethod async def _collectCpuStats(): psutil.cpu_percent(interval=None) while True: await asyncio.sleep(0.1) CPU_STATS.set(psutil.cpu_percent(interval=None)) async def main(request: StandaloneLambdaRequest) -> dict: """Main route""" logger.info("Request processing starts") value = request.json.get("value") start = time.time() await asyncio.sleep(value) LAMBDA_REQUEST_DURATION.observe(time.time() - start) return {"result": "Metrics collected"}request examplefrom luna3.luna_lambda.luna_lambda import LambdaApi SERVER_ORIGIN = "http://lambda_address:lambda_port" # Replace by your values before start SERVER_API_VERSION = 1 lambdaApi = LambdaApi(origin=SERVER_ORIGIN, api=SERVER_API_VERSION) lambdaId, accountId = "your_lambda_id", "your_account_id" # Replace by your values before start def makeRequest(): reply = lambdaApi.proxyLambdaPost(lambdaId=lambdaId, path="main", accountId=accountId, body={"value": 0.1}) return reply if __name__ == "__main__": response = makeRequest() print(response.json)
Example of metrics that will be collected by prometheus after /main request:
...
# HELP cpu_stats Lambda cpu load
# TYPE cpu_stats gauge
cpu_stats{lambda_id="d95a072a-3b8a-461d-ad23-5df95ddd300d"} 17.4
# HELP lambda_request_duration Request duration
# TYPE lambda_request_duration summary
lambda_request_duration_count{lambda_id="d95a072a-3b8a-461d-ad23-5df95ddd300d"} 1.0
lambda_request_duration_sum{lambda_id="d95a072a-3b8a-461d-ad23-5df95ddd300d"} 0.10052204132080078