2323use Google \Cloud \Trace \Span ;
2424use Google \Cloud \Trace \Trace ;
2525use OpenCensus \Trace \Tracer \TracerInterface ;
26+ use OpenCensus \Trace \Span as OCSpan ;
2627
2728/**
2829 * This implementation of the ExporterInterface use the BatchRunner to provide
7071 */
7172class StackdriverExporter implements ExporterInterface
7273{
73- const VERSION = '0.1.0 ' ;
74-
75- // These are Stackdriver Trace's common attributes
76- const AGENT = 'g.co/agent ' ;
77- const COMPONENT = '/component ' ;
78- const ERROR_MESSAGE = '/error/message ' ;
79- const ERROR_NAME = '/error/name ' ;
80- const HTTP_CLIENT_CITY = '/http/client_city ' ;
81- const HTTP_CLIENT_COUNTRY = '/http/client_country ' ;
82- const HTTP_CLIENT_PROTOCOL = '/http/client_protocol ' ;
83- const HTTP_CLIENT_REGION = '/http/client_region ' ;
84- const HTTP_HOST = '/http/host ' ;
85- const HTTP_METHOD = '/http/method ' ;
86- const HTTP_REDIRECTED_URL = '/http/redirected_url ' ;
87- const HTTP_STATUS_CODE = '/http/status_code ' ;
88- const HTTP_URL = '/http/url ' ;
89- const HTTP_USER_AGENT = '/http/user_agent ' ;
90- const PID = '/pid ' ;
91- const TID = '/tid ' ;
92-
93- const GAE_APPLICATION_ERROR = 'g.co/gae/application_error ' ;
94- const GAE_APP_MODULE = 'g.co/gae/app/module ' ;
95- const GAE_APP_MODULE_VERSION = 'g.co/gae/app/module_version ' ;
96- const GAE_APP_VERSION = 'g.co/gae/app/version ' ;
74+ const ATTRIBUTE_MAP = [
75+ OCSpan::ATTRIBUTE_HOST => '/http/host ' ,
76+ OCSpan::ATTRIBUTE_PORT => '/http/port ' ,
77+ OCSpan::ATTRIBUTE_METHOD => '/http/method ' ,
78+ OCSpan::ATTRIBUTE_PATH => '/http/url ' ,
79+ OCSpan::ATTRIBUTE_USER_AGENT => '/http/user_agent ' ,
80+ OCSpan::ATTRIBUTE_STATUS_CODE => '/http/status_code '
81+ ];
9782
9883 use BatchTrait;
9984
@@ -155,7 +140,6 @@ public function __construct(array $options = [])
155140 */
156141 public function report (TracerInterface $ tracer )
157142 {
158- $ this ->processSpans ($ tracer );
159143 $ spans = $ this ->convertSpans ($ tracer );
160144
161145 if (empty ($ spans )) {
@@ -182,40 +166,43 @@ public function report(TracerInterface $tracer)
182166 }
183167
184168 /**
185- * Perform any pre-conversion modification to the spans
169+ * Convert spans into Stackdriver's expected JSON output format.
170+ *
171+ * @access private
186172 *
187173 * @param TracerInterface $tracer
188- * @param array $headers [optional] Array of headers to read from instead of $_SERVER
174+ * @return Span[] Representation of the collected trace spans ready for serialization
189175 */
190- public function processSpans (TracerInterface $ tracer, $ headers = null )
176+ public function convertSpans (TracerInterface $ tracer )
191177 {
192- // detect common attributes
193- $ this -> addCommonAttributes ( $ tracer , $ headers );
178+ // transform OpenCensus Spans to Google\Cloud\Trace\Spans
179+ return array_map ([ $ this , ' mapSpan ' ], $ tracer -> spans () );
194180 }
195181
196- /**
197- * Convert spans into Zipkin's expected JSON output format.
198- *
199- * @param TracerInterface $tracer
200- * @param Trace $trace
201- * @return array Representation of the collected trace spans ready for serialization
202- */
203- public function convertSpans (TracerInterface $ tracer )
182+ private function mapSpan ($ span )
204183 {
205- $ traceId = $ tracer ->spanContext ()->traceId ();
184+ return new Span ($ span ->traceId (), [
185+ 'name ' => $ span ->name (),
186+ 'startTime ' => $ span ->startTime (),
187+ 'endTime ' => $ span ->endTime (),
188+ 'spanId ' => $ span ->spanId (),
189+ 'parentSpanId ' => $ span ->parentSpanId (),
190+ 'attributes ' => $ this ->mapAttributes ($ span ->attributes ()),
191+ 'stackTrace ' => $ span ->stackTrace ()
192+ ]);
193+ }
206194
207- // transform OpenCensus Spans to Google\Cloud\Trace\Spans
208- return array_map (function ($ span ) use ($ traceId ) {
209- return new Span ($ traceId , [
210- 'name ' => $ span ->name (),
211- 'startTime ' => $ span ->startTime (),
212- 'endTime ' => $ span ->endTime (),
213- 'spanId ' => $ span ->spanId (),
214- 'parentSpanId ' => $ span ->parentSpanId (),
215- 'attributes ' => $ span ->attributes (),
216- 'stackTrace ' => $ span ->stackTrace ()
217- ]);
218- }, $ tracer ->spans ());
195+ private function mapAttributes (array $ attributes )
196+ {
197+ $ newAttributes = [];
198+ foreach ($ attributes as $ key => $ value ) {
199+ if (array_key_exists ($ key , self ::ATTRIBUTE_MAP )) {
200+ $ newAttributes [self ::ATTRIBUTE_MAP [$ key ]] = $ value ;
201+ } else {
202+ $ newAttributes [$ key ] = $ value ;
203+ }
204+ }
205+ return $ newAttributes ;
219206 }
220207
221208 /**
@@ -232,54 +219,4 @@ protected function getCallback()
232219
233220 return [self ::$ client , $ this ->batchMethod ];
234221 }
235-
236- private function addCommonAttributes (&$ tracer , $ headers = null )
237- {
238- $ headers = $ headers ?: $ _SERVER ;
239- $ spans = $ tracer ->spans ();
240- if (empty ($ spans )) {
241- return ;
242- }
243- $ rootSpan = $ spans [0 ];
244-
245- $ attributeMap = [
246- self ::HTTP_URL => ['REQUEST_URI ' ],
247- self ::HTTP_METHOD => ['REQUEST_METHOD ' ],
248- self ::HTTP_CLIENT_PROTOCOL => ['SERVER_PROTOCOL ' ],
249- self ::HTTP_USER_AGENT => ['HTTP_USER_AGENT ' ],
250- self ::HTTP_HOST => ['HTTP_HOST ' , 'SERVER_NAME ' ],
251- self ::GAE_APP_MODULE => ['GAE_SERVICE ' ],
252- self ::GAE_APP_MODULE_VERSION => ['GAE_VERSION ' ],
253- self ::HTTP_CLIENT_CITY => ['HTTP_X_APPENGINE_CITY ' ],
254- self ::HTTP_CLIENT_REGION => ['HTTP_X_APPENGINE_REGION ' ],
255- self ::HTTP_CLIENT_COUNTRY => ['HTTP_X_APPENGINE_COUNTRY ' ]
256- ];
257- foreach ($ attributeMap as $ attributeKey => $ headerKeys ) {
258- if ($ val = $ this ->detectKey ($ headerKeys , $ headers )) {
259- $ tracer ->addAttribute ($ attributeKey , $ val , ['span ' => $ rootSpan ]);
260- }
261- }
262-
263- $ responseCode = http_response_code ();
264- if ($ responseCode == 301 || $ responseCode == 302 ) {
265- foreach (headers_list () as $ header ) {
266- if (substr ($ header , 0 , 9 ) == 'Location: ' ) {
267- $ this ->rootSpan ->addAttribute (self ::HTTP_REDIRECTED_URL , substr ($ header , 10 ));
268- break ;
269- }
270- }
271- }
272- $ tracer ->addAttribute (self ::PID , '' . getmypid (), ['span ' => $ rootSpan ]);
273- $ tracer ->addAttribute (self ::AGENT , 'opencensus-php [ ' . self ::VERSION . '] ' , ['span ' => $ rootSpan ]);
274- }
275-
276- private function detectKey (array $ keys , array $ array )
277- {
278- foreach ($ keys as $ key ) {
279- if (array_key_exists ($ key , $ array )) {
280- return $ array [$ key ];
281- }
282- }
283- return null ;
284- }
285222}
0 commit comments