{'fraction_non_alphanumeric': 0.036059701492537316, 'fraction_numerical': 0.0060895522388059705, 'mean_word_length': 4.426141885325559, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 0, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
Estimation from Partially Sampled Distributed Traces

Sampling is often a necessary evil to reduce the processing and storage costs of distributed tracing. In this work, we describe a scalable and adaptive sampling approach that can preserve events of interest better than the widely used head-based sampling approach. Sampling rates can be chosen individually and independently for every span, allowing to take span attributes and local resource constraints into account. The resulting traces are often only partially and not completely sampled which complicates statistical analysis. To exploit the given information, an unbiased estimation algorithm is presented. Even though it does not need to know whether the traces are complete, it reduces the estimation error in many cases compared to considering only complete traces.


INTRODUCTION
Distributed tracing [4,5,11,13,14] has become an important tool for monitoring and failure diagnosis of large distributed systems. It measures the behavior and the performance of individual operations also called spans. By propagating parent span contexts including a unique trace identifier, that is generated at the endpoint (the entry point into the monitored system), to child spans allows to derive the hierarchical causal relationships between collected spans. In this way, the set of collected spans sharing the same trace identifier will form a directed acyclic graph, which is called a trace. These traces allow to see, find, and understand far-reaching dependencies across process boundaries and are invaluable when investigating failures or performance issues.
Tracing involves some inherent performance overhead and leads to additional processing and storage costs. Span contexts must be sent from parent to child spans across process boundaries to enable linking spans to traces. Measuring latencies or response times and capturing exceptions or errors result in higher resource consumption. Transmitting observed data over the network to a preprocessor or a storage layer further increases costs. If monitoring and capturing everything is not an option, on-demand collection or sampling are the remaining alternatives. The first approach does not allow for post-mortem analysis. Repetitions of the same failure must occur after activating trace collection to gain further insight. Demand-driven collection corresponds to sampling with rates 0 or 1, depending on whether the collection is off or on, respectively. In the general case, the free choice of the sampling rate allows a smooth adjustment of the collection behavior between those two extremes. The larger the sampling rate, the more information is collected, and the higher the chance that problems and failures can be analyzed and explained by the recorded data.
To minimize the loss of information, a clever sampling strategy is crucial. For example, stratified sampling [2] can be used to collect interesting events like slow service calls or errors at higher rates than frequent events representing normal behavior to reduce the variance. A major complication is that at the time of the sampling decision, it is often not known whether a trace is of interest or not.

Overview
After elaborating the state of the art like head-based sampling and tail-based sampling, we will present a different approach called partial trace sampling. Unlike head-based sampling, which uses the same sampling decision for all spans of the trace, partial trace sampling generalizes this by allowing the sampling rate to be set individually and independently for every span. This flexibility enables better adaptation to local resource constraints and recording meaningful or infrequently accessed spans with higher probabilities.
Based on a mathematical model describing the new sampling approach, a general estimation algorithm is developed that allows the unbiased estimation of arbitrary quantities from partially sampled traces, like how often some service called some other service . The results of this work allow deriving requirements and recommendations for monitoring frameworks like OpenTelemetry [1] to produce sampled trace data that is more useful for downstream statistical analysis.
As we have found that the performance of the proposed estimation algorithm strongly depends on the choice of sampling rates, a restriction to a discrete set of values makes sense. In particular, limiting sampling rates to powers of 1 2 also has other benefits we will discuss. Unfortunately, this restriction conflicts with traditional rate-limiting sampling [13]. Therefore, we present a workaround that can adhere to a prescribed discrete set of sampling rates. Furthermore, as partial trace sampling can lead to fragmented traces, we briefly discuss which information could be added to the span context to reduce the estimation error for queries relying on hierarchical relationships.

Head-Based Trace Sampling
Head-based sampling [7,8,12,13], also called up-front sampling [11], is a simple and widely used sampling approach for traces. The sampling decision for the whole trace is made at the endpoint and propagated together with the unique trace identifier as part of the span context to descendant spans which respect the sampling decision made for the root span. The simplicity of head-based sampling allows straightforward estimation. The reciprocal of the sampling rate used for the root span corresponds to the extrapolation factor, also called adjusted weight [3], that applies to the whole trace.
Choosing an appropriate sampling rate is challenging. At the endpoint, which is the origin of a trace, not much is known. The attributes of the root span often do not reveal which branches will be called. Furthermore, they rarely indicate anomalous backend behavior and are therefore often not suited for filtering interesting traces. Furthermore, the sampling rate must be chosen small enough not to violate any constraints on data collection at backend services.
Without knowledge about what is going on in the backend the choice of sampling rates may be difficult. Therefore, a feedback loop is often required to allow dynamic adaptation of the sampling behavior [13]. This requires an orchestration service with a back channel to control the sampling rates at endpoints. This rather indirect way of controlling the amount of collected spans leads to a slow adaptation to new situations. In particular, sudden jumps in load can violate the limits of data collection, and sudden drops in load can lead to more loss of information than necessary. In addition, head-based sampling is not capable of responding quickly to back pressure caused by the span processing pipeline.

Tail-Based Trace Sampling
Tail-based sampling [7,8,12,13], also called response-based sampling [11] is another popular technique to reduce the number of traces that need to be stored. In contrast to head-based sampling, this approach collects all spans, and only after reconstructing the trace, a sampling decision is made. Since all information of a trace is available, the sampling rate can be chosen more intelligently than with head-based sampling. However, this comes with significant additional network and memory costs, because all spans of the same trace have to be sent to the same instance of a preprocessing service that buffers them until the trace has completed. Additional complexity is introduced if the preprocessing service needs to be scalable. Adding or removing instances requires rerouting spans of a trace to balance the work load which carries a risk of obtaining incomplete traces. Tail-based sampling can be combined with other more upstream sampling techniques like head-based sampling or partial trace sampling which is described in the following.

Partial Trace Sampling
If network costs are a major concern or rerouting and buffering spans is not an option, the sampling decision must be made immediately for each individual observed span. Independent sampling decisions for spans of the same trace would lead to a very small probability to record all spans of a trace simultaneously. Therefore, the sampling decision of different spans has to be consistent to increase the probability to collect all spans of a trace. Head-based sampling, for example, achieves consistency by propagating the sampling decision to child spans.
Another way to enforce consistent sampling is to share a uniform random number ∈ [0, 1) across all spans of a trace and sample the span only if the sampling condition < is satisfied [14]. If the same sampling rate is used for all spans, the result will be equivalent to that of head-based sampling with rate . Generating a random number at the root and propagating it as part of the span context together with the trace identifier to child spans is one option to realize a common random number [10]. Alternatively, to avoid the propagation of an additional field, a hash value calculated from the trace identifier can be used instead [14]. For that, a fast high-quality hash function [15] is needed with outputs that can be regarded as uniform random values. If the trace identifiers are already generated using some high-quality random number generator, they could be directly mapped to the range [0, 1) and used as random numbers. Similar to propagating a random number this would save computation costs as hashing the trace identifier for every single span is avoided.
If the sampling rate is not chosen homogeneously across all spans, the sampling decision is no longer the same for all spans, and as a result, traces may be only partially sampled. Google's tracing system called Dapper [14], for example, allows increasing the sampling rates for child spans [9]. In this way, rarely called branches are sampled with a higher probability and more details are preserved that would otherwise have been lost with pure head-based sampling. This can lead to incomplete traces since only subgraphs of the same trace might be captured.
If backend services are called by many different endpoints or many times within the same trace, it is also useful to allow reducing the sampling rates for child spans. Hence, in the most general case, we want the sampling rates to be chosen independently for every single span as exemplified in [10]. This, of course, will lead to a fragmentation of traces, if spans in the middle are not recorded. Nevertheless, there is still a reasonable chance to record complete traces, if the spans are sampled consistently using a shared random number as described before. By definition, the smallest sampling rate used by any span corresponds to the probability that a trace is fully recorded.
Unlike head-based sampling, partial trace sampling does not need global orchestration to set appropriate sampling rates at endpoints. They can be chosen independently, for example, to satisfy local constraints. While local constraints also limit the maximum sampling rate of head-based sampling, partial trace sampling is more flexible and allows using larger sampling rates for other spans and thus collecting more information. The number of complete traces would be the same for both, head-based and partial sampling. However, the additional fragments of other traces collected can reduce the estimation error. Often it is not necessary to know the full trace. Sometimes problems can be explained by looking at certain branches only. Even if different fragments are not connected because some span in the middle has not been sampled, we know that they must belong to the same trace because of the common trace identifier. Therefore, partially sampled traces are still useful to explain far-reaching dependencies.
To make the most out of the given information, incomplete traces need to be incorporated for estimation, which is not trivial in the general case. In particular, correct estimation of quantities that depend on multiple spans of a trace is not obvious. For example, estimating how often some service called another service also depends on the sampling rate of the intermediate spans connecting service and , because only when collecting the hierarchical connection between and , we really know that called . To the best of our knowledge, there is no prior work that considers estimation from partially and consistently sampled traces. Therefore, we will present an estimation algorithm capable of providing unbiased estimates for arbitrary quantities of interest.

METHODOLOGY
Partial trace sampling allows to choose an individual sampling rate for every single span of a trace. The sampling rate function : X → (0, 1] will describe the corresponding sampling rate for every span ∈ X. Here, X denotes the set of all spans of a given trace. The sampling rate of span ∈ X is given by ( ). If ∈ [0, 1) is the random number shared across all spans of the trace and used for consistent sampling decisions, the span will be sampled if and only if < ( ) ⇔ span is sampled. (1) The sampling rates ( ) ∈ (0, 1] can be freely chosen for each trace. However, we do not allow zero sampling rates, as unbiased estimation of something that is never sampled is impossible. Furthermore, we require that the sampling rates do not depend on the shared random number . This implies, that it is not allowed to choose the sampling rate based on sampling decisions of other spans of the same trace. If is calculated from the trace identifier, the chosen sampling rate must also not depend on the trace identifier. However, the sampling rate may depend on any other span attributes. This allows, for example, to sample spans with long durations or with errors at a higher frequency. The sampling rate may even depend on attributes or sampling rates of other spans if the corresponding information is propagated and hence available when the sampling rate is needed for the sampling decision. The calculation of the sampling rate may also incorporate any local or global resource constraints.
For a trace with set of spans X, partial trace sampling can be mathematically described using a sampling function that maps X to a corresponding subset of sampled spans The sampling function is defined as and also requires the shared uniform random number ∈ [0, 1) and the sampling rate function .
Obviously, in the special case that ( ) is constant for all spans of a trace, either all or none of the spans will be sampled. This corresponds to the behavior of head-based sampling. To have the same sampling rate for every span of a trace, the sampling rate chosen for the root span must be propagated to descendent spans. This is in contrast to traditional head-based sampling where usually just a flag as specified for the W3C trace context [6] indicating the sampling decision of the root is propagated. Passing on the sampling rate has the advantage of immediately knowing the sampling rate and thus also the adjusted weight for each span. If only a flag representing the sampling decision is propagated, the sampling rate for non-root spans will not be known until the corresponding root span is available, from which the sampling rate can eventually be retrieved.
Partial trace sampling will result in a fully sampled trace, if the random number is smaller than all individual span sampling rates, mathematically expressed as The corresponding probability is given by the minimum sampling rate Unfortunately, for a given set of sampled spans, it is often not obvious whether a trace has been completely sampled or not. Furthermore, the sampling rates of discarded spans are usually not reported and hence the minimum sampling rate might not be known. Especially, if only some leaf spans are missing, the situation will not be clear. This is different from head-based sampling where the sampling rate is guaranteed to be equal for all spans and traces are always fully sampled. If it is important to know whether a trace is complete, partial trace sampling would require collecting extra information like the number of children of each span. Luckily, knowing the completeness of traces is often not necessary as shown in the following sections.

Trace Analysis
Traces are collected for various purposes. The analysis of individual traces, such as those associated with a particular failed action on a web page, is one important use case. When sampling is active, regardless of the method used, there is no guarantee that the traces of interest were recorded. If partial trace sampling is used, there is at least a higher chance that at least parts of the trace have been sampled. Traces can be easily sorted by completeness [10]. By definition, the traces with the smallest shared random number are the most complete.
Collective trace analysis is another important use case. Instead of looking at individual traces, information is extracted from all available traces using statistical means. Typically, we would like to know the sum of a certain quantity over all traces represented as sets of spans X (X 1 , X 2 , . . .) = ∑︁ (X ).
Here = (X) is a function that maps the set of spans X of a given trace to a real number. Depending on what we would like to know, can be arbitrarily defined, as demonstrated by the following examples: • If we are interested in the total count of traces we would simply have (X) := 1. • If we want to count traces with a certain property, would be the corresponding indicator function, returning 1 or 0 dependent on whether the trace given by the set of spans X has that property or not, respectively. For example, we might be interested in the number of traces calling some particular service . If X contains at least one span corresponding to a call to , the returned value would be 1. • If we want to determine the average call tree depth, (X) would be defined to return the depth of the graph spanned by the set of spans X. Together with the estimate for the total count of traces an estimate of the average depth can be obtained.

Estimation Problem
When traces are sampled partially, only subsets of spans Y = (X ; , ) ⊆ X will be available for estimation. Complicating matters, we are often unable to verify their completeness if, for example, only leaf spans are missing. Moreover, the existence of traces, for which not a single span has been collected, is not even known. Therefore, it is challenging to find an estimator = (Y ), which provides an unbiased estimate for (X ) based on the partially sampled set of spans Y and thus satisfies (X ) = E ( (Y )). We must have (∅) = 0, since a trace with none of its spans sampled cannot contribute to the estimate.
If we have found such an unbiased estimator, the composite estimator will consequently be an unbiased estimator for , hence If the random values , that are used for sampling different traces, are independent, the corresponding variance will be given by As a consequence, the estimation problem boils down to finding an unbiased estimator = (Y ) for the quantity of interest (X ) from a single trace, which allows to omit the subscript in the following.

Naive Estimation Approach
A simple approach is to use only complete traces for estimation. This requires knowing whether the set of sampled spans Y is equal to the true set of spans X of a given trace, which may often not be the case, as mentioned earlier. The naive estimator weights the quantity (Y) of complete traces by the inverse of the probability that Y = X given by Pr(Y = X) = 1 min ∈Y ( ) according to (2) By definition, this estimator is unbiased E ( naive (Y)) = (X) and it can be shown that its variance is The naive estimator does not incorporate partially sampled traces and hence does not use all information available. Therefore, we will present another unbiased estimation approach that does not require knowing the completeness of traces and performs provably better when the quantity of interest satisfies certain conditions.

Quantity Function
For the simple estimator, the quantity function needs to be defined only for sets of spans X that represent complete traces. In the following we require to be also defined for all nonempty subsets of spans Y with ∅ ⊂ Y ⊆ X. As long as Y is distinguishable from the set of spans of a complete trace, we allow the value of (Y) to be arbitrarily chosen. Otherwise, (Y) must be equal to the true value of that trace.
As discussed later, it is beneficial if the extended function satisfies certain conditions. Therefore, we call bounded, if ∅ ⊂ Y ⊆ X with X denoting the set of spans of a complete trace implies for all Y. In case (X) < 0, the interval [0, 2 (X)] is interpreted as for all Y 1 and Y 2 . Obviously, if is monotonic, it will also be bounded, which can easily seen when setting Y 1 = Y and Y 2 = X. Many quantities are inherently monotonic, such as the number of spans of a trace (X) = |X|. However, there are quantities, which are not even bounded. For example, consider a trace that invokes two different services and in that order. The set of spans of this trace is X = { a , b }. Suppose we are interested in counting all traces that called but not . Obviously, we would then have (X) = 0. For the subset X ′ = { a } we must have (X ′ ) = 1, if there is no additional information indicating whether X ′ represents a complete trace or not. In the case of doubt, it must be assumed that the trace is complete. It follows that 0 = (X) < (X ′ ) = 1, while ∅ ⊂ X ′ ⊂ X showing that is not bounded and thus not monotonic as well.
In the case where it is always known whether a set of spans represents a completely sampled trace, can always be defined to be monotonic by simply returning zero for incomplete sets of spans, hence Y ⊂ X ⇒ (Y) = 0. This is very similar to the naive estimator naive (3), which ignores incomplete traces. In fact, the new estimator we will propose is equivalent to naive , if the definition of is extended this way.

Estimation by Example
To illustrate the basic idea of the new estimator, we first discuss a concrete example. Suppose we are interested in estimating the total number of spans, (X) = |X|. Furthermore, consider a trace X = { p , c } with exactly two spans, a parent (root) span p and a child span c . Both are sampled with rates ( p ) and ( c ), respectively, satisfying 0 < ( c ) < ( p ) < 1. Dependent on the shared random number , three different outcomes are possible for the sampled trace Y = (X; , ) ⊆ X: (1) ∈ [ ( p ), 1) ⇒ Y = ∅: Since none of both spans is sampled, there is nothing to contribute to the estimate and we have (Y) = 0. As is uniformly distributed, this case occurs with a probability of Pr(Y = ∅) = 1 − ( p ).
(2) ∈ [ ( c ), ( p )) ⇒ Y = { p }: Only the parent span is sampled in this case, which occurs with a probability of Pr(Y = { p }) = ( p ) − ( c ). Since there is no information about child spans, we also do not know ( c ). Using just the information available, namely the parent span including its sampling rate ( p ), we have to assume that the trace originally consisted of only a single span. Hence, we have to weight this span with 1/ ( p ) to account for the unseen spans in order to get a supposed unbiased estimate given by This occurs with a probability of If we would proceed as in the previous case, weighting the two observed spans with 1/ ( c ) and using the estimate ({ p , c }) = 2/ ( c ), we would introduce a bias, because when calculating the weighted average over all three cases, which is not what we would expect for an unbiased estimator. We must set ({ p , c }) = 1/ ( c ) + 1/ ( p ) to fix the bias introduced by the previous case and to get E ( (Y)) = 2.
This simple example demonstrates the basic idea of our new estimation approach. More complete traces must account for the estimation errors that are made with less complete traces.

New Estimation Approach
In the general case, we consider the set of distinct sampling rates of all spans in X denoted in ascending order by 1 < 2 < . . . < , where is the total number of those values. Dependent on the random number , the spans X may be sampled in different ways such that the sampled set of spans Y is nonempty. If ∈ [ , +1 ) (with 0 := 0 and 0 ≤ < ) the sampled set of spans will be Y = (X; , ) = (X; , ). If ∈ [ 0 , 1 ) = [0, min ∈X ( )) implying Y = (X; 0, ) = X, the trace will be fully sampled. The different outcomes are distributed according to the probabilities Pr(Y = (X; , )) = +1 − . With a probability of 1 − nothing is sampled, hence Pr(Y = ∅) = 1 − = 1 − max ∈X ( ). Let us focus on the case ∈ [ , +1 ) with 0 ≤ < . According to the way consistent sampling works, the sampled set of spans Y will have = − distinct sampling rates denoted in ascending order by 1 < 2 < . . . < and given by the relationship = + . These sampling rates can also be obtained directly from Y as { 1 , 2 , . . . , } = ∈Y ( ). The new estimator as function of a nonempty set of consistently sampled spans Y can then be written as (Y; , )) .
It is easy to show that all these expressions are equivalent. The third expression requires 0 to be defined such that (Y; 0 , ) = Y. Hence, any value from [0, 1 ) could be used for 0 .
According to Lemma 1 and Lemma 2, both given and proved in the appendix, this estimator is unbiased and has variance In contrast to the naive estimator naive (3), new does not need to know whether Y corresponds to a fully sampled trace. If is bounded as defined by (4), new also leads to a smaller estimation error as Var ( new (Y)) ≤ Var ( naive (Y)) according to Lemma 3. If is monotonic as defined by (5) and a trace is sampled using different sampling rate functions 1 and 2 , where the second dominates the first meaning that 1 ( ) ≤ 2 ( ) for all ∈ X, the variance will satisfy Var ( new ( (X; , 1 ))) ≥ Var ( new ( (X; , 2 ))) according to Lemma 4. This is not surprising, as higher sample rates lead to more collected spans and more information that can be used to obtain more accurate estimates.

Estimating Counts
Counting spans or traces that match certain filter criteria is a very common task. For these special cases, the new estimator (6) can be significantly simplified. When estimating the number of matching spans from a partially sampled trace, the quantity of interest would be (X) = |X ∩ A|, where A denotes the universe of matching spans. It can be shown that estimator (6) simplifies to (see Lemma 5) This is actually what we would have expected as it is simply the sum of inverse sampling rates of all matching spans. When counting matching traces, would correspond to an indicator function. If is monotonic the estimator can be simplified to (see Lemma 6) with := max{ ∈ {1, 2, . . . , } : ( (Y; −1 , )) = 1} and 0 := 0. Hence, the extrapolation factor depends on the minimum sampling rate of all spans needed to match the given filter criteria.

Practical Considerations
Algorithm 1 summarizes the new estimation approach based on (6). The number of loop iterations is given by the number of unique sampling rates found in the sampled set of spans Y. In the case where each sampling rate of each span is distinct and the evaluation of (Y) takes O (|Y|) time, the algorithm will exhibit an O (|Y| 2 ) time complexity. Some quantities allow optimizations that reduce the worst case time complexity. However, in the general case, the time complexity can only be reduced, if the number of different sampling rates is limited.

Algorithm 1 Estimation algorithm.
Input: Y ⊲ nonempty set of sampled spans of the same trace : Y → (0, 1] ⊲ returns sampling rate of given span ⊲ extracts quantity of interest from given set of spans Output: ⊲ unbiased estimate for quantity of interest As a solution, we propose a restriction to values of a geometric sequence ( ) ∈ {1, , 2 , 3 , . . .} with ∈ (0, 1). In this way, the expected number of different sampling rates present in the sample of spans will be constant. Assume that the maximum sampling rate of all spans in X is = max ∈X ( ) with some ≥ 0. The sampled set of spans Y can be nonempty only if < according to (1). Given < , the conditional probability that spans with sampling rate + are sampled, is Pr( < + | < ) = , where ≥ 0. Therefore, the expected number of different sampling rates of spans in Y must be bounded by ∞ =0 = 1 1− = O (1). A further advantage of using a discrete set of sampling rates is that the index ≥ 0 can be used to encode the sampling rate instead of its numerical representation. Likewise, the shared random number can be encoded as integer as well, because for the sampling decision (1) it is only relevant to which of the intervals [ +1 , ) with ≥ 0 the shared random value belongs to. Therefore, it is sufficient to propagate the index of the corresponding interval instead of the numerical representation of . The sampling decision simplifies to a plain integer comparison ≥ ⇔ span is sampled, where denotes the exponent of the sampling rate ( ) = and indicates ∈ [ +1 , ). Since is uniformly distributed, the index will be geometrically distributed with success probability (1 − ) as It can therefore be drawn directly from the corresponding geometric distribution without having to generate first. According to our experience, = 1 2 is a good choice as it gives enough freedom to select the sampling rate while also offering some other nice benefits: • A single byte is able to encode all relevant sampling rates. Similarly, a single byte is sufficient to encode the index of the interval that surrounds the shared random number which reduces the information that needs to propagated to child spans. • As already discussed, it is favorable to directly generate indicating the interval [ +1 , ) enclosing the uniform random number . Drawing a random value from a geometric distribution with a success probability of = 1 2 can be efficiently implemented by simply taking the number of leading zeros of a uniformly distributed random integer. This is a very cheap and natively supported operation on most processors.
• If all possible sampling rates are reciprocals of integers as is the case for all values of a geometric sequence with coefficient = 1 2 , estimates of integer quantities like counts will be integers as well. ∈ Z and 1 ∈ Z imply (Y) ∈ Z according to (3) and (6). It is desirable to have estimates from the same number system, as consumers of estimated quantities do not have to deal with rounding. The obvious downside of being limited to a discrete set of values is that the sampling rate cannot take on any arbitrary value. However, this is important for techniques like rate-limiting sampling [13]. Therefore, a workaround is presented in the following, that allows freely choosing the effective sampling rate while still having the span sampling rates from the given discrete set.

Rate-Limiting Sampling
A way to limit the rate of sampled spans is to choose the sampling rate proportional to the average time Δ between subsequent spans [13], = min(1, Δ · max ) where max denotes the rate limit. The average time between subsequent spans needs to be estimated from the timestamps of the most recent spans. In the simplest case, it is just the elapsed time since the last span.
The restriction to a discrete set of sampling rates makes ratelimiting sampling more difficult as the sampling rate cannot be freely chosen. Assume that the desired sampling rate is and lies between the two possible sampling rates +1 and with ≥ 0 such that ∈ ( +1 , ]. The idea is to randomly select one of these two sampling rates for each span. This obviously then leads to an effective sampling rate that is in between. In particular, if is chosen with a probability of − +1 − +1 and +1 with the corresponding complementary probability of (1 − − +1 − +1 ), the effective sampling rate will be − +1 − +1 + +1 (1 − − +1 − +1 ) = as desired.

Span Context
Partially sampled traces often break into multiple fragments of spans. Therefore, it is feasible to propagate additional information along the trace identifier to allow better reconstruction of hierarchical relationships between spans, even when they cannot be directly lined up. If the sampling decision is negative, it makes little sense to propagate the span identifier to child spans, as it would be a reference to a non-sampled and therefore later unknown span. Instead, if a span is not sampled, it is more useful to add the identifier of the last sampled ancestor span to the propagated context. In this way, child spans can be linked to the nearest sampled ancestor span. When the number of consecutive non-sampled spans is also counted and propagated, even the degree of the ancestor would be known.
This additional information about hierarchical relationships between spans are very helpful for queries such as counting the number of times a service called some other service . If we can determine the hierarchical relationship between and without knowing all the spans in between, the indicator function (8) will be nonzero for smaller sampled sets of spans, eventually reducing the variance according to (7).

CONCLUSION
We have presented a theoretical foundation for partial trace sampling that allows sampling rates for spans to be chosen independently without requiring a global service to orchestrate sampling rates at endpoints, as is the case with head-based sampling. Given the same local constraints, partial trace sampling can collect more detailed information, especially from rarely called branches. The proposed unbiased estimator can exploit this additional information without knowing the completeness of traces and provably reduces the estimation error in many cases.