npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

elven-instrumentation-serverless-plugin

v1.1.0

Published

Serverless Framework plugin to add Elven observability layers and environment variables automatically.

Readme

Instrumentação Lambda com Serverless Framework e Elven Plugin

Guia prático para instrumentar funções AWS Lambda com o elven-instrumentation-serverless-plugin, incluindo seleção automática de layers para node, python, ruby, javaagent e javawrapper.


Visão geral

O plugin automatiza três partes da instrumentação:

  1. Adiciona a layer OpenTelemetry correta para o runtime da função.
  2. Adiciona a Elven Log Extension correta para x86_64 ou arm64.
  3. Injeta as variáveis de ambiente de traces e logs sem sobrescrever o que já existe na função.

O runtime efetivo é resolvido nesta ordem:

  1. functions.<nome>.elvenRuntime
  2. custom.elvenLayerPlugin.runtime
  3. node

Se provider.runtime ou functions.<nome>.runtime indicarem claramente outra linguagem, o plugin mostra um warning, mas não muda a configuração sozinho.


Instalação

npm install --save-dev elven-instrumentation-serverless-plugin
plugins:
  - elven-instrumentation-serverless-plugin

Quick start

Serviço homogêneo

service: minha-api

provider:
  name: aws
  runtime: python3.12
  region: us-east-1
  stage: ${opt:stage, 'dev'}

plugins:
  - elven-instrumentation-serverless-plugin

custom:
  elvenLayerPlugin:
    tenant: "seu-tenant-id"
    token: "seu-api-token"
    collector_endpoint: "https://otel-collector.minha-infra.com:4318"
    runtime: python

functions:
  hello:
    handler: handler.hello

Serviço misto

service: mixed-service

provider:
  name: aws
  runtime: nodejs22.x
  region: us-east-1

plugins:
  - elven-instrumentation-serverless-plugin

custom:
  elvenLayerPlugin:
    tenant: "seu-tenant-id"
    token: "seu-api-token"
    collector_endpoint: "https://otel-collector.minha-infra.com:4318"
    runtime: node

functions:
  api:
    handler: src/api.handler

  worker:
    handler: src/worker.handler
    elvenRuntime: python
    architecture: arm64

  billing:
    handler: com.example.BillingHandler::handleRequest
    elvenRuntime: javaagent

Output esperado

✅ [Elven] Instrumented function: mixed-service_dev_api (runtime=node, arch=x86_64)
✅ [Elven] Instrumented function: mixed-service_dev_worker (runtime=python, arch=arm64)
✅ [Elven] Instrumented function: mixed-service_dev_billing (runtime=javaagent, arch=x86_64)
📍 [Elven] Region: us-east-1
🧩 [Elven] Default runtime: node
🏗️  [Elven] Default architecture: x86_64
📦 [Elven] Instrumented functions: 3

Configuração do plugin

Todas as opções ficam em custom.elvenLayerPlugin:

custom:
  elvenLayerPlugin:
    tenant: "seu-tenant-id"
    token: "seu-api-token"
    collector_endpoint: "https://otel-collector.minha-infra.com:4318"

    region: "us-east-1"
    runtime: "node"                    # node | python | ruby | javaagent | javawrapper
    architecture: "x86_64"
    logs_endpoint: "https://loki.elvenobservability.com"
    log_version: "8"
    log_version_arm64: "7"
    enabled_instrumentations: "http,express,pg"
    disabled_instrumentations: "flask,sidekiq"
    layers:
      - "arn:aws:lambda:us-east-1:111111111111:layer:custom-otel:5"
      - "arn:aws:lambda:us-east-1:111111111111:layer:custom-log:9"

Opções disponíveis

| Opção | Default | Descrição | | --- | --- | --- | | tenant | "default-tenant" | Tenant da Elven | | token | "" | Token de autenticação | | collector_endpoint | "" | URL do seu collector OTLP | | region | us-east-1 | Região usada nos ARNs das layers | | runtime | node | Runtime padrão do serviço | | architecture | x86_64 | Arquitetura padrão do serviço | | logs_endpoint | https://loki.elvenobservability.com | URL base do Loki | | log_version | 8 | Versão da log extension para x86_64 | | log_version_arm64 | 7 | Versão da log extension para arm64 | | enabled_instrumentations | lista default Node | Instrumentações habilitadas para Node.js | | disabled_instrumentations | "" | Instrumentações desabilitadas para Node, Python ou Ruby | | layers | automático | Override completo das layers para todas as funções instrumentadas |

Valores suportados para runtime

| Valor | Observação | | --- | --- | | node | valor recomendado para Node.js | | nodejs | alias aceito para node | | python | usa a layer Python | | ruby | usa a layer Ruby | | javaagent | usa o Java agent | | javawrapper | usa o Java wrapper |


Controle por função

Desabilitar a instrumentação

functions:
  internal:
    handler: src/internal.handler
    disableElven: true

Escolher runtime por função

functions:
  api:
    handler: src/api.handler
    # usa o runtime global

  worker:
    handler: src/worker.handler
    elvenRuntime: python

  billing:
    handler: com.example.BillingHandler::handleRequest
    elvenRuntime: javawrapper

Sobrescrever variáveis manualmente

O plugin não sobrescreve variáveis de ambiente já definidas na função:

functions:
  heavy-worker:
    handler: src/worker.handler
    elvenRuntime: python
    environment:
      OTEL_TRACES_SAMPLER: "traceidratio"
      OTEL_TRACES_SAMPLER_ARG: "0.1"

Variáveis de ambiente injetadas

Comuns a todos os runtimes

| Variável | Valor | | --- | --- | | AWS_LAMBDA_EXEC_WRAPPER | /opt/otel-handler | | OTEL_SERVICE_NAME | {service}_{stage}_{function} | | OTEL_TRACES_SAMPLER | always_on | | OTEL_LAMBDA_TRACE_MODE | capture | | OTEL_PROPAGATORS | tracecontext,baggage,xray | | OTEL_RESOURCE_ATTRIBUTES | service.name=...,environment=... | | OTEL_EXPORTER_OTLP_ENDPOINT | collector_endpoint | | TENANT_ID | tenant | | SERVICE_NAME | {service}_{stage}_{function} | | RESOURCES_ATTRIBUTES | service=...,environment=... | | API_TOKEN | token | | LOKI_URL | logs_endpoint | | LOKI_TENANT_ID | tenant | | LOKI_AUTH_TOKEN | token | | DEBUG | false |

Específicas por runtime

| Runtime | Variáveis | | --- | --- | | node | OTEL_NODE_ENABLED_INSTRUMENTATIONS, OTEL_NODE_DISABLED_INSTRUMENTATIONS | | python | OTEL_PYTHON_DISABLED_INSTRUMENTATIONS | | ruby | OTEL_RUBY_DISABLED_INSTRUMENTATIONS | | javaagent | OTEL_INSTRUMENTATION_COMMON_DEFAULT_ENABLED=true | | javawrapper | OTEL_INSTRUMENTATION_COMMON_DEFAULT_ENABLED=true |

enabled_instrumentations é uma opção específica de Node.js. Para Python e Ruby, o plugin só mapeia disabled_instrumentations.


Layers padrão

OpenTelemetry por runtime

| Runtime | ARN | | --- | --- | | node | arn:aws:lambda:{region}:184161586896:layer:opentelemetry-nodejs-0_21_0:1 | | python | arn:aws:lambda:{region}:184161586896:layer:opentelemetry-python-0_19_0:1 | | ruby | arn:aws:lambda:{region}:184161586896:layer:opentelemetry-ruby-0_13_0:1 | | javaagent | arn:aws:lambda:{region}:184161586896:layer:opentelemetry-javaagent-0_19_0:1 | | javawrapper | arn:aws:lambda:{region}:184161586896:layer:opentelemetry-javawrapper-0_19_0:1 |

Elven Log Extension por arquitetura

| Arquitetura | ARN | | --- | --- | | x86_64 | arn:aws:lambda:{region}:911167927290:layer:elven-lambda-log-extension:{version} | | arm64 | arn:aws:lambda:{region}:911167927290:layer:elven-lambda-log-extension-arm64:{version} |

Override completo das layers

Ao definir custom.elvenLayerPlugin.layers, o plugin usa exatamente a lista informada em todas as funções instrumentadas:

custom:
  elvenLayerPlugin:
    runtime: ruby
    layers:
      - "arn:aws:lambda:us-east-1:111111111111:layer:custom-otel:5"
      - "arn:aws:lambda:us-east-1:111111111111:layer:custom-log:9"

As variáveis de ambiente continuam sendo resolvidas pelo runtime efetivo.


Exemplos completos

Node.js padrão

provider:
  name: aws
  runtime: nodejs22.x

custom:
  elvenLayerPlugin:
    tenant: ${env:ELVEN_TENANT}
    token: ${env:ELVEN_TOKEN}
    collector_endpoint: "https://otel-collector.minha-infra.com:4318"
    runtime: node

Python com arm64

provider:
  name: aws
  runtime: python3.12
  architecture: arm64

custom:
  elvenLayerPlugin:
    tenant: ${env:ELVEN_TENANT}
    token: ${env:ELVEN_TOKEN}
    collector_endpoint: "https://otel-collector.minha-infra.com:4318"
    runtime: python

Serviço misto Node + Python + Java

custom:
  elvenLayerPlugin:
    tenant: ${env:ELVEN_TENANT}
    token: ${env:ELVEN_TOKEN}
    collector_endpoint: "https://otel-collector.minha-infra.com:4318"
    runtime: node

functions:
  api:
    handler: src/api.handler

  worker:
    handler: src/worker.handler
    elvenRuntime: python

  billing:
    handler: com.example.BillingHandler::handleRequest
    elvenRuntime: javaagent

Troubleshooting

Erro de layer inexistente

Verifique:

  1. region
  2. log_version e log_version_arm64
  3. se o runtime efetivo está correto para a função

Exemplo para validar a layer Node:

aws lambda get-layer-version \
  --layer-name opentelemetry-nodejs-0_21_0 \
  --version-number 1 \
  --region us-east-1 \
  --query "LayerVersionArn"

Warning de runtime incompatível

Exemplo típico:

  • provider.runtime: python3.12
  • custom.elvenLayerPlugin.runtime: node

Nesse caso o plugin avisa, mas continua usando o runtime Elven explícito.

Traces ou logs não aparecem

Verifique:

  1. collector_endpoint
  2. tenant e token
  3. se a função recebeu a layer OTel correta para o runtime
  4. se LOKI_URL está configurado como URL base, sem /loki/api/v1/push

FAQ

Preciso configurar cada função individualmente?
Não. Só use elvenRuntime quando a função fugir do runtime global.

O plugin funciona com outros runtimes além de Node.js?
Sim. Há suporte automático para node, python, ruby, javaagent e javawrapper.

O plugin sobrescreve minhas layers?
Não. Ele só adiciona o que falta e evita duplicação.

O plugin sobrescreve minhas variáveis de ambiente?
Não. Variáveis já definidas na função têm prioridade.

Posso continuar usando layers customizadas?
Sim. Use custom.elvenLayerPlugin.layers.

Como atualizo a versão das layers padrão?
Para a log extension, altere log_version e log_version_arm64. Para a layer OTel, use layers se precisar sair dos defaults do plugin.

Quais runtimes do Lambda fazem mais sentido hoje?
Em abril de 2026, para novas funções AWS Lambda, a recomendação geral é preferir nodejs22.x ou nodejs24.x, python3.12+, java21 e ruby3.3+, conforme compatibilidade do seu projeto e da sua versão do Serverless Framework.