1616
1717import math
1818import json
19+ import re
1920
2021try :
2122 import flask
@@ -55,12 +56,13 @@ def get_request_data_from_flask():
5556 """Get http_request and trace data from flask request headers.
5657
5758 Returns:
58- Tuple[Optional[dict], Optional[str]]:
59- Data related to the current http request and the trace_id for the
60- request. Both fields will be None if a flask request isn't found.
59+ Tuple[Optional[dict], Optional[str], Optional[str]]:
60+ Data related to the current http request, trace_id, and span_id for
61+ the request. All fields will be None if a django request isn't
62+ found.
6163 """
6264 if flask is None or not flask .request :
63- return None , None
65+ return None , None , None
6466
6567 # build http_request
6668 http_request = {
@@ -73,27 +75,26 @@ def get_request_data_from_flask():
7375 "protocol" : flask .request .environ .get (_PROTOCOL_HEADER ),
7476 }
7577
76- # find trace id
77- trace_id = None
78+ # find trace id and span id
7879 header = flask .request .headers .get (_FLASK_TRACE_HEADER )
79- if header :
80- trace_id = header .split ("/" , 1 )[0 ]
80+ trace_id , span_id = _parse_trace_span (header )
8181
82- return http_request , trace_id
82+ return http_request , trace_id , span_id
8383
8484
8585def get_request_data_from_django ():
8686 """Get http_request and trace data from django request headers.
8787
8888 Returns:
89- Tuple[Optional[dict], Optional[str]]:
90- Data related to the current http request and the trace_id for the
91- request. Both fields will be None if a django request isn't found.
89+ Tuple[Optional[dict], Optional[str], Optional[str]]:
90+ Data related to the current http request, trace_id, and span_id for
91+ the request. All fields will be None if a django request isn't
92+ found.
9293 """
9394 request = _get_django_request ()
9495
9596 if request is None :
96- return None , None
97+ return None , None , None
9798
9899 # convert content_length to int if it exists
99100 content_length = None
@@ -112,32 +113,55 @@ def get_request_data_from_django():
112113 "protocol" : request .META .get (_PROTOCOL_HEADER ),
113114 }
114115
115- # find trace id
116- trace_id = None
116+ # find trace id and span id
117117 header = request .META .get (_DJANGO_TRACE_HEADER )
118- if header :
119- trace_id = header .split ("/" , 1 )[0 ]
118+ trace_id , span_id = _parse_trace_span (header )
120119
121- return http_request , trace_id
120+ return http_request , trace_id , span_id
121+
122+
123+ def _parse_trace_span (header ):
124+ """Given an X_CLOUD_TRACE header, extract the trace and span ids.
125+
126+ Args:
127+ header (str): the string extracted from the X_CLOUD_TRACE header
128+ Returns:
129+ Tuple[Optional[dict], Optional[str]]:
130+ The trace_id and span_id extracted from the header
131+ Each field will be None if not found.
132+ """
133+ trace_id = None
134+ span_id = None
135+ if header :
136+ try :
137+ split_header = header .split ("/" , 1 )
138+ trace_id = split_header [0 ]
139+ header_suffix = split_header [1 ]
140+ # the span is the set of alphanumeric characters after the /
141+ span_id = re .findall (r"^\w+" , header_suffix )[0 ]
142+ except IndexError :
143+ pass
144+ return trace_id , span_id
122145
123146
124147def get_request_data ():
125148 """Helper to get http_request and trace data from supported web
126149 frameworks (currently supported: Flask and Django).
127150
128151 Returns:
129- Tuple[Optional[dict], Optional[str]]:
130- Data related to the current http request and the trace_id for the
131- request. Both fields will be None if a supported web request isn't found.
152+ Tuple[Optional[dict], Optional[str], Optional[str]]:
153+ Data related to the current http request, trace_id, and span_id for
154+ the request. All fields will be None if a django request isn't
155+ found.
132156 """
133157 checkers = (
134158 get_request_data_from_django ,
135159 get_request_data_from_flask ,
136160 )
137161
138162 for checker in checkers :
139- http_request , trace_id = checker ()
163+ http_request , trace_id , span_id = checker ()
140164 if http_request is not None :
141- return http_request , trace_id
165+ return http_request , trace_id , span_id
142166
143- return None , None
167+ return None , None , None
0 commit comments