Collector Processor
Sobre o processor são as ações que podemos quando recebermos um dado de telemetria. Eles são opcionais, mas alguns são recomendados. Aqui temos uma lista do que podemos fazer.
Na mesma idéia melhorar a performance, aqui temos o batch para processamento em lote. A configuração default é suficiente para começar e caso necessário faça ajuste se necessário.
Vamos utilizar o resource processor que se aplica somente ao pipeline de traces para incluir, modificar ou deletar um atributo de recurso em cada um dos spans recebidos.
Já fizemos a inclusão de tags no SDK nessa parte do código.
const resource = new Resource({
"team.ownner": "devsecops-team",
repository: "https://gitlab.com/davidpuziol/opentelemetry-project",
site: "https://gitlab.com/davidpuziol/opentelemetry-project",
});
Não precisamos remover, apenas poderíamos ter feito isso também no collector ou manter os dois se for necessário. Para o nosso exemplo vamos manter o que a SDK fez, mas incluir um e deletar outro criado pela SDK.
#Codigo...
processors:
batch: # quando não ajustamos as opções estamos utilizando os valores default.
resource:
attributes:
- key: testcollectorstudy
value: collector_is_good
action: insert
- key: repository
action: delete
#Codigo...
# E vamos usar esse processor
Configurações de services
service:
extensions:
- health_check
pipelines:
traces:
receivers:
- otlp
processors:
- batch # precisa ser o primeiro
- resource # Vamos incluir aquele atributo
exporters:
- otlphttp
metrics:
receivers:
- otlp
processors:
- batch # Aqui vou usar somente o batch
exporters:
- prometheus
Conferindo o Jaeger depois de um curl para localhost:8081/todos, podemos ver a inclusão desse atributo.
A tag repository foi eliminada, mas esqueci de marcar. Fiz isso pois estava com valores duplicados.
Na mesma idéia temos o sampler para tomar decisão do que devemos ou não manter, porém agora temos mais poderemos se comparado quando utilizamos o SDK. Ao contrário da SDK, agora vamos tomar a decisão de manter ou não a amostra ao final do processo e não no começo dele por isso chamamos de Tail Samping.
Vamos aplicar ao nosso código e eliminar o Head Sampler do nosso código.
// import { ParentBasedSampler, TraceIdRatioBasedSampler } from "@opentelemetry/sdk-trace-node";
// import { CustomSampler } from './customSampler'
//código..
function start(serviceName: string) {
//código..
// const sampler = new ParentBasedSampler({
// root: new CustomSampler(),
// });
const sdk = new NodeSDK({
resource,
traceExporter,
instrumentations,
// sampler,
});
}
Só vamos manter a amostra se satisfazer alguma das regras.
# Código...
processors:
batch:
resource:
attributes:
- key: testcollectorstudy
value: collector_is_good
action: insert
tail_sampling:
# Tempo de espera esperar para receber todos os spans de um trace antes de tomar uma decisão de amostragem
decision_wait: 10s
# Numero máximo de traces que podem estar em processo de decisão
num_traces: 100
# Indica a expectativa de quantos novos traces chegam por segundo. Isso ajuda ao collector a se preparar em recursos. Se não passado é 0, o que sinifica que não há expectativa.
expected_new_traces_per_sec: 10
decision_cache:
sampled_cache_size: 100_000 # 100 mil traces
non_sampled_cache_size: 100_000
policies:
[
{
name: high_latence,
type: latency,
latency: {threshold_ms: 500}
},
{
name: http_error_only,
type: numeric_attribute,
numeric_attribute: {http_status_code: key1, min_value: 500, max_value: 599}
},
]
# Código...
service:
extensions:
- health_check
pipelines:
traces:
receivers:
- otlp
processors:
# Se esquecer de utilizar o processo nada vai acontecer!
- tail_sampling # Vamos adicionar antes do batch
- batch
- resource
# Código...
# Código...
Vamos então aproveitar os endpoints que temos.
curl http://localhost:8081/todos
{"todos":[{"name":"Implementar tracing"},{"name":"Configurar OpenTelemetry"},{"name":"Configurar exporters"},{"name":"Adicionar métricas"}],"user":{"username":"David Prata","userId":12345}}%
curl http://localhost:8081/todos\?fail\=1
Internal Server Error
curl http://localhost:8081/todos\?slow\=1
{"todos":[{"name":"Implementar tracing"},{"name":"Configurar OpenTelemetry"},{"name":"Configurar exporters"},{"name":"Adicionar métricas"}],"user":{"username":"David Prata","userId":12345}}%
Podemos observar que somente temos no Jaeger as requisições acima de 500ms e com error.