aboutsummaryrefslogtreecommitdiffstats
path: root/container-search/src/main/java/com/yahoo/search/statistics/TimingSearcher.java
blob: 5d036b8fa20e1002e41fd182dda4a3da74ad041a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.search.statistics;

import com.yahoo.component.ComponentId;
import com.yahoo.component.chain.dependencies.Before;
import com.yahoo.search.statistics.TimingSearcherConfig.Timer;
import com.yahoo.prelude.Ping;
import com.yahoo.prelude.Pong;
import com.yahoo.search.Query;
import com.yahoo.search.Result;
import com.yahoo.search.cluster.PingableSearcher;
import com.yahoo.search.searchchain.Execution;
import com.yahoo.search.statistics.TimeTracker.Activity;
import com.yahoo.statistics.Statistics;
import com.yahoo.statistics.Value;

/**
 * A searcher which is intended to be useful as a general probe for
 * measuring time consumption a search chain.
 *
 * @author Steinar Knutsen
 * @deprecated Will be removed on Vespa 8
 */
@Before("rawQuery")
@Deprecated
public class TimingSearcher extends PingableSearcher {

    private Value measurements;
    private final boolean measurePing;
    private final boolean measureSearch;
    private final boolean measureFill;
    private static final Parameters defaultParameters = new Parameters(null, Activity.SEARCH);

    public static class Parameters {
        final String eventName;
        final Activity pathToSample;

        public Parameters(String eventName, Activity pathToSample) {
            super();
            this.eventName = eventName;
            this.pathToSample = pathToSample;
        }
    }

    TimingSearcher(ComponentId id, Parameters setUp, Statistics manager) {
        super(id);
        if (setUp == null) {
            setUp = defaultParameters;
        }
        String eventName = setUp.eventName;
        if (eventName == null || "".equals(eventName)) {
            eventName = id.getName();
        }
        measurements = new Value(eventName, manager, new Value.Parameters()
                .setNameExtension(true).setLogMax(true).setLogMin(true)
                .setLogMean(true).setLogSum(true).setLogInsertions(true)
                .setAppendChar('_'));

        measurePing = setUp.pathToSample == Activity.PING;
        measureSearch = setUp.pathToSample == Activity.SEARCH;
        measureFill = setUp.pathToSample == Activity.FILL;
    }

    public TimingSearcher(ComponentId id, TimingSearcherConfig config, Statistics manager) {
        this(id, buildParameters(config, id.getName()), manager);
    }

    private static Parameters buildParameters(
            TimingSearcherConfig config, String searcherName) {
        for (int i = 0; i < config.timer().size(); ++i) {
            Timer t = config.timer(i);
            if (t.name().equals(searcherName)) {
                return buildParameters(t);
            }
        }
        return null;
    }

    private static Parameters buildParameters(Timer t) {
        Activity m;
        Timer.Measure.Enum toSample = t.measure();
        if (toSample == Timer.Measure.FILL) {
            m = Activity.FILL;
        } else if (toSample == Timer.Measure.PING) {
            m = Activity.PING;
        } else {
            m = Activity.SEARCH;
        }
        return new Parameters(t.eventname(), m);
    }

    private long preMeasure(boolean doIt) {
        if (doIt) {
            return System.currentTimeMillis();
        } else {
            return 0L;
        }
    }

    private void postMeasure(boolean doIt, long start) {
        if (doIt) {
            long elapsed = System.currentTimeMillis() - start;
            measurements.put(elapsed);
        }
    }

    @Override
    public void fill(Result result, String summaryClass, Execution execution) {
        long start = preMeasure(measureFill);
        super.fill(result, summaryClass, execution);
        postMeasure(measureFill, start);
    }

    @Override
    public Pong ping(Ping ping, Execution execution) {
        long start = preMeasure(measurePing);
        Pong pong = execution.ping(ping);
        postMeasure(measurePing, start);
        return pong;
    }

    @Override
    public Result search(Query query, Execution execution) {
        long start = preMeasure(measureSearch);
        Result result = execution.search(query);
        postMeasure(measureSearch, start);
        return result;
    }

    /**
     * This method is only included for testing.
     */
    public void setMeasurements(Value measurements) {
        this.measurements = measurements;
    }

    @Override
    public void deconstruct() {
        // avoid dangling, duplicate loggers
        measurements.cancel();
        super.deconstruct();
    }

}