lib/graphql/metrics/tracer.rb in graphql-metrics-5.0.3 vs lib/graphql/metrics/tracer.rb in graphql-metrics-5.0.4

- old
+ new

@@ -17,10 +17,16 @@ GRAPHQL_GEM_TRACING_FIELD_KEYS = [ GRAPHQL_GEM_TRACING_FIELD_KEY = 'execute_field', GRAPHQL_GEM_TRACING_LAZY_FIELD_KEY = 'execute_field_lazy' ] + include GraphQL::Metrics::Trace + + def initialize + # no-op, but don't want the behavior from GraphQL::Metrics::Trace + end + def trace(key, data, &block) # NOTE: Context doesn't exist yet during lexing, parsing. context = data[:query]&.context skip_tracing = context&.fetch(GraphQL::Metrics::SKIP_GRAPHQL_METRICS_ANALYSIS, false) return yield if skip_tracing @@ -52,132 +58,13 @@ GraphQL::Metrics::INLINE_FIELD_TIMINGS when GRAPHQL_GEM_TRACING_LAZY_FIELD_KEY GraphQL::Metrics::LAZY_FIELD_TIMINGS end - trace_field(context_key, data, &block) + trace_field(context_key, data[:query], &block) else return yield end - end - - private - - PreContext = Struct.new( - :multiplex_start_time, - :multiplex_start_time_monotonic, - :parsing_start_time_offset, - :parsing_duration, - :lexing_start_time_offset, - :lexing_duration - ) do - def reset - self[:multiplex_start_time] = nil - self[:multiplex_start_time_monotonic] = nil - self[:parsing_start_time_offset] = nil - self[:parsing_duration] = nil - self[:lexing_start_time_offset] = nil - self[:lexing_duration] = nil - end - end - - def pre_context - # NOTE: This is used to store timings from lexing, parsing, validation, before we have a context to store - # values in. Uses thread-safe Concurrent::ThreadLocalVar to store a set of values per thread. - @pre_context ||= Concurrent::ThreadLocalVar.new(PreContext.new) - @pre_context.value - end - - def capture_multiplex_start_time - pre_context.multiplex_start_time = GraphQL::Metrics.current_time - pre_context.multiplex_start_time_monotonic = GraphQL::Metrics.current_time_monotonic - - yield - end - - def capture_lexing_time - timed_result = GraphQL::Metrics.time { yield } - - pre_context.lexing_start_time_offset = timed_result.start_time - pre_context.lexing_duration = timed_result.duration - - timed_result.result - end - - def capture_parsing_time - timed_result = GraphQL::Metrics.time { yield } - - pre_context.parsing_start_time_offset = timed_result.start_time - pre_context.parsing_duration = timed_result.duration - - timed_result.result - end - - # Also consolidates parsing timings (if any) from the `pre_context` - def capture_validation_time(context) - # Queries may already be lexed and parsed before execution (whether a single query or multiplex). - # If we don't have those values, use some sane defaults. - if pre_context.lexing_duration.nil? - pre_context.lexing_start_time_offset = pre_context.multiplex_start_time - pre_context.lexing_duration = 0.0 - end - if pre_context.parsing_duration.nil? - pre_context.parsing_start_time_offset = pre_context.multiplex_start_time - pre_context.parsing_duration = 0.0 - end - - timed_result = GraphQL::Metrics.time(pre_context.multiplex_start_time_monotonic) { yield } - - ns = context.namespace(CONTEXT_NAMESPACE) - - ns[MULTIPLEX_START_TIME] = pre_context.multiplex_start_time - ns[MULTIPLEX_START_TIME_MONOTONIC] = pre_context.multiplex_start_time_monotonic - ns[LEXING_START_TIME_OFFSET] = pre_context.lexing_start_time_offset - ns[LEXING_DURATION] = pre_context.lexing_duration - ns[PARSING_START_TIME_OFFSET] = pre_context.parsing_start_time_offset - ns[PARSING_DURATION] = pre_context.parsing_duration - ns[VALIDATION_START_TIME_OFFSET] = timed_result.time_since_offset - ns[VALIDATION_DURATION] = timed_result.duration - - timed_result.result - end - - def capture_analysis_time(context) - ns = context.namespace(CONTEXT_NAMESPACE) - - timed_result = GraphQL::Metrics.time(ns[MULTIPLEX_START_TIME_MONOTONIC]) { yield } - - ns[ANALYSIS_START_TIME_OFFSET] = timed_result.time_since_offset - ns[ANALYSIS_DURATION] = timed_result.duration - - timed_result.result - end - - def capture_query_start_time(context) - ns = context.namespace(CONTEXT_NAMESPACE) - ns[QUERY_START_TIME] = GraphQL::Metrics.current_time - ns[QUERY_START_TIME_MONOTONIC] = GraphQL::Metrics.current_time_monotonic - - yield - end - - def trace_field(context_key, data) - ns = data[:query].context.namespace(CONTEXT_NAMESPACE) - offset_time = ns[GraphQL::Metrics::QUERY_START_TIME_MONOTONIC] - start_time = GraphQL::Metrics.current_time_monotonic - - result = yield - - duration = GraphQL::Metrics.current_time_monotonic - start_time - time_since_offset = start_time - offset_time if offset_time - - path_excluding_numeric_indicies = data[:path].select { |p| p.is_a?(String) } - ns[context_key][path_excluding_numeric_indicies] ||= [] - ns[context_key][path_excluding_numeric_indicies] << { - start_time_offset: time_since_offset, duration: duration - } - - result end end end end