# frozen_string_literal: true require 'json' module OpenTracing module Instrumentation module Redis # SpanBuilder create span with tags and logs class SpanBuilder extend Forwardable def initialize( config: Config.new, error_writer: Common::ErrorWriter.new ) @config = config @error_writer = error_writer end def_delegators :@config, :tracer, :span_name, :component, :log_args, :log_reply def_delegators :@error_writer, :write_error def start_active_scope(connection_class, peer_addr) tags = build_tags(connection_class, peer_addr) tracer.start_active_span( span_name, tags: tags, ) end def build_tags(connection_class, peer_addr) { 'span.kind' => 'client', 'component' => component, 'peer.address' => peer_addr, 'peer.service' => 'redis', 'redis.driver' => connection_class.to_s, }.compact end REDACTED_ARG = ['*'].freeze def write_log_command(span, command) command_name, *args = command args_value = log_args ? JSON.dump(args) : REDACTED_ARG * args.size span.log_kv( event: EVENT_WRITE, 'redis.command': command_name, 'redis.args': args_value, ) end def write_error_reply(span, reply) return unless reply.is_a?(::Redis::CommandError) span.set_tag('error', true) span.log_kv( 'error.kind': 'redis_error', message: reply.to_s, event: EVENT_READ, ) end def write_log_reply(span, reply) write_error_reply(span, reply) return unless log_reply span.log_kv( event: EVENT_READ, 'redis.reply': JSON.dump(reply), ) end end end end end