@@ -26,134 +26,192 @@ composer require opentracing/opentracing
2626## Usage
2727
2828When consuming this library one really only need to worry about a couple of key
29- abstractions: the ` Tracer::startSpan ` method, the ` Span ` interface, and binding
30- a ` Tracer ` at bootstrap time. Here are code snippets demonstrating some important
31- use cases:
29+ abstractions: the ` Tracer::startActiveSpan ` and ` Tracer::startSpan ` method,
30+ the ` Span ` interface, and binding a ` Tracer ` at bootstrap time. Here are code snippets
31+ demonstrating some important use cases:
3232
3333### Singleton initialization
3434
3535The simplest starting point is to set the global tracer. As early as possible, do:
3636
3737``` php
38- use OpenTracing\GlobalTracer;
39- use AnOpenTracingImplementation\MyTracer;
40-
41- GlobalTracer::set(new MyTracer());
38+ use OpenTracing\GlobalTracer;
39+
40+ GlobalTracer::set(new MyTracerImplementation());
4241```
4342
4443### Creating a Span given an existing Request
4544
46- To start a new ` Span ` , you can use the ` StartSpanFromContext ` method.
45+ To start a new ` Span ` , you can use the ` startActiveSpan ` method.
4746
4847``` php
49- use OpenTracing\Formats;
50- use OpenTracing\GlobalTracer;
48+ use OpenTracing\Formats;
49+ use OpenTracing\GlobalTracer;
50+
51+ ...
52+
53+ $spanContext = GlobalTracer::get()->extract(
54+ Formats\HTTP_HEADERS,
55+ getallheaders()
56+ );
5157
58+ function doSomething() {
5259 ...
5360
54- $spanContext = GlobalTracer::get()->extract(
55- Formats\HTTP_HEADERS,
56- $request->getHeaders()
57- );
58-
59- function doSomething(SpanContext $spanContext, ...) {
60- ...
61-
62- $span = GlobalTracer::get()->startSpan('my_span', [
63- 'child_of' => $spanContext,
64- ]);
65-
66- ...
67-
68- $span->log([
69- 'event' => 'soft error',
70- 'type' => 'cache timeout',
71- 'waiter.millis' => 1500,
72- ])
73-
74- $span->finish();
75- }
61+ $span = GlobalTracer::get()->startActiveSpan('my_span', ['child_of' => $spanContext]);
62+
63+ ...
64+
65+ $span->log([
66+ 'event' => 'soft error',
67+ 'type' => 'cache timeout',
68+ 'waiter.millis' => 1500,
69+ ])
70+
71+ $span->finish();
72+ }
7673```
7774
7875### Starting an empty trace by creating a "root span"
7976
80- It's always possible to create a "root" ` Span ` with no parent or other causal
81- reference.
77+ It's always possible to create a "root" ` Span ` with no parent or other causal reference.
8278
8379``` php
84- $span = $tracer->startSpan('my_span');
85- ...
86- $span->finish();
80+ $span = $tracer->startActiveSpan('my_first_span');
81+ ...
82+ $span->finish();
83+ ```
84+
85+ ### Active Spans and Scope Manager
86+
87+ When using the ` Tracer::startActiveSpan ` function the underlying tracer uses an
88+ abstraction called scope manager to keep track of the currently active span.
89+
90+ Starting an active span will always use the currently active span as a parent.
91+ If no parent is available, then the newly created span is considered to be the
92+ root span of the trace.
93+
94+ Unless you are using asynchronuous code that tracks multiple spans at the same
95+ time, such as when using cURL Multi Exec or MySQLi Polling you are better
96+ of just using ` Tracer::startActiveSpan ` everywhere in your application.
97+
98+ The currently active span gets automatically closed and deactivated from the scope
99+ when you call ` $span->finish() ` as you can see in the previous example.
100+
101+ If you don't want a span to automatically close when ` Span::finish() ` is called
102+ then you must pass the option ` 'close_span_on_finish'=> false, ` to the ` $options `
103+ argument of ` startActiveSpan ` .
104+
105+ An example of a linear, two level deep span tree using active spans looks like
106+ this in PHP code:
107+
108+ ``` php
109+ $root = $tracer->startActiveSpan('php');
110+
111+ $controller = $tracer->startActiveSpan('controller');
112+
113+ $http = $tracer->startActiveSpan('http');
114+ file_get_contents('http://php.net');
115+ $http->finish();
116+
117+ $controller->finish();
118+ $root->finish();
87119```
88120
89- ### Creating a ( child) Span given an existing ( parent) Span
121+ #### Creating a child span assigning parent manually
90122
91123``` php
92- function xyz(Span $parentSpan, ...) {
93- ...
94- $span = GlobalTracer::get()->startSpan(
95- 'my_span',
96- [
97- 'child_of' => $parentSpan,
98- ]
99- );
100-
101- $span->finish();
102- ...
103- }
124+ $parent = GlobalTracer::get()->startSpan('parent');
125+
126+ $child = GlobalTracer::get()->startSpan('child', [
127+ 'child_of' => $parent
128+ ]);
129+
130+ ...
131+
132+ $child->finish();
133+
134+ ...
135+
136+ $parent->finish();
137+ ```
138+
139+ #### Creating a child span using automatic active span management
140+
141+ Every new span will take the active span as parent and it will take its spot.
142+
143+ ``` php
144+ $parent = GlobalTracer::get()->startActiveSpan('parent');
145+
146+ ...
147+
148+ /*
149+ * Since the parent span has been created by using startActiveSpan we don't need
150+ * to pass a reference for this child span
151+ */
152+ $child = GlobalTracer::get()->startActiveSpan('my_second_span');
153+
154+ ...
155+
156+ $child->finish();
157+
158+ ...
159+
160+ $parent->finish();
104161```
105162
106163### Serializing to the wire
107164
108165``` php
109- use OpenTracing\GlobalTracer;
110- use OpenTracing\Formats;
111-
112- ...
113-
114- $tracer = GlobalTracer::get();
115-
116- $spanContext = $tracer->extract(
166+ use GuzzleHttp\Client;
167+ use OpenTracing\Formats;
168+
169+ ...
170+
171+ $tracer = GlobalTracer::get();
172+
173+ $spanContext = $tracer->extract(
174+ Formats\HTTP_HEADERS,
175+ getallheaders()
176+ );
177+
178+ try {
179+ $span = $tracer->startSpan('my_span', ['child_of' => $spanContext]);
180+
181+ $client = new Client;
182+
183+ $headers = [];
184+
185+ $tracer->inject(
186+ $span->getContext(),
117187 Formats\HTTP_HEADERS,
118- $request->getHeaders()
188+ $headers
119189 );
120-
121- try {
122- $span = $tracer->startSpan('my_span', ['child_of' => $spanContext]);
123-
124- $client = new GuzzleHttp\Client;
125-
126- $headers = [];
127-
128- $tracer->inject(
129- $span->getContext(),
130- Formats\HTTP_HEADERS,
131- $headers
132- );
133-
134- $request = new \GuzzleHttp\Psr7\Request('GET', 'http://myservice', $headers);
135- $client->send($request);
136- ...
137- } catch (\Exception $e) {
138- ...
139- }
140- ...
190+
191+ $request = new \GuzzleHttp\Psr7\Request('GET', 'http://myservice', $headers);
192+ $client->send($request);
193+ ...
194+
195+ } catch (\Exception $e) {
196+ ...
197+ }
198+ ...
141199```
142200
143201### Deserializing from the wire
144202
145- When using http header for context propagation you can use either the ` Request ` or the ` $_SERVER ` variable:
203+ When using http header for context propagation you can use either the ` Request ` or the ` $_SERVER `
204+ variable:
146205
147206``` php
148- use OpenTracing\GlobalTracer;
149- use OpenTracing\Formats;
150-
151- $request = Request::createFromGlobals();
152- $tracer = GlobalTracer::get();
153- $spanContext = $tracer->extract(Formats\HTTP_HEADERS, $request->getHeaders());
154- $tracer->startSpan('my_span', [
155- 'child_of' => $spanContext,
156- ]);
207+ use OpenTracing\GlobalTracer;
208+ use OpenTracing\Formats;
209+
210+ $tracer = GlobalTracer::get();
211+ $spanContext = $tracer->extract(Formats\HTTP_HEADERS, getallheaders());
212+ $tracer->startSpan('my_span', [
213+ 'child_of' => $spanContext,
214+ ]);
157215```
158216
159217### Flushing Spans
@@ -167,31 +225,30 @@ cause problems for Tracer implementations. This is why the PHP API contains a
167225``` php
168226use OpenTracing\GlobalTracer;
169227
170- // Do application work, buffer spans in memory
171228$application->run();
172229
173- fastcgi_finish_request();
174-
175- $tracer = GlobalTracer::get();
176- $tracer->flush(); // release buffer to backend
230+ register_shutdown_function(function() use ($tracer) {
231+ /* Flush the tracer to the backend */
232+ $tracer = GlobalTracer::get();
233+ $tracer->flush();
234+ });
177235```
178236
179237This is optional, tracers can decide to immediately send finished spans to a
180238backend. The flush call can be implemented as a NO-OP for these tracers.
181239
182-
183240### Using Span Options
184241
185242Passing options to the pass can be done using either an array or the
186243SpanOptions wrapper object. The following keys are valid:
187244
188245- ` start_time ` is a float, int or ` \DateTime ` representing a timestamp with arbitrary precision.
189246- ` child_of ` is an object of type ` OpenTracing\SpanContext ` or ` OpenTracing\Span ` .
190- - ` references ` is an array of ` OpenTracing\Reference ` .
247+ - ` references ` is an array of ` OpenTracing\Reference ` .
191248- ` tags ` is an array with string keys and scalar values that represent OpenTracing tags.
192249
193250``` php
194- $span = $tracer->createSpan ('my_span', [
251+ $span = $tracer->startActiveSpan ('my_span', [
195252 'child_of' => $spanContext,
196253 'tags' => ['foo' => 'bar'],
197254 'start_time' => time(),
@@ -217,5 +274,5 @@ Tracers will throw an exception if the requested format is not handled by them.
217274
218275## Coding Style
219276
220- Opentracing PHP follows the [ PSR-2] ( https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md )
277+ OpenTracing PHP follows the [ PSR-2] ( https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md )
221278coding standard and the [ PSR-4] ( https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader.md ) autoloading standard.
0 commit comments