Skip to content

Commit 48eb4fa

Browse files
authored
Fixes and tweaks falcon plugin (#151)
1 parent 930f4ec commit 48eb4fa

File tree

3 files changed

+46
-57
lines changed

3 files changed

+46
-57
lines changed

skywalking/plugins/sw_falcon.py

Lines changed: 36 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -15,84 +15,65 @@
1515
# limitations under the License.
1616
#
1717

18-
from skywalking import Layer, Component
18+
from skywalking import Layer, Component, config
1919
from skywalking.trace.carrier import Carrier
20-
from skywalking.trace.context import get_context
20+
from skywalking.trace.context import get_context, NoopContext
2121
from skywalking.trace.span import NoopSpan
22-
from skywalking.trace.tags import TagHttpMethod, TagHttpURL, TagHttpParams, TagHttpStatusCode
22+
from skywalking.trace.tags import TagHttpMethod, TagHttpURL, TagHttpParams, TagHttpStatusCode, TagHttpStatusMsg
2323

2424

2525
def install():
26-
from falcon import API, request, response
26+
from falcon import API, request, RequestOptions
2727

2828
_original_falcon_api = API.__call__
29-
_original_falcon_handle_exception = API._handle_exception
30-
31-
def params_tostring(params):
32-
return "\n".join([k + "=" + v for k, v in params.items()])
3329

3430
def _sw_falcon_api(this: API, env, start_response):
3531
context = get_context()
3632
carrier = Carrier()
37-
headers = get_headers(env)
33+
req = request.Request(env, RequestOptions())
34+
headers = req.headers
35+
method = req.method
36+
3837
for item in carrier:
39-
key = item.key.replace("_", "-") if "_" in item.key else item.key
40-
if key.capitalize() in headers:
41-
item.val = headers[key.capitalize()]
42-
with context.new_entry_span(op="/", carrier=carrier) as span:
43-
span.layer = Layer.Http
44-
span.component = Component.Falcon
38+
key = item.key.upper()
39+
if key in headers:
40+
item.val = headers[key]
4541

46-
from falcon import RequestOptions
42+
span = NoopSpan(NoopContext()) if config.ignore_http_method_check(method) \
43+
else context.new_entry_span(op=req.path, carrier=carrier)
4744

48-
req = request.Request(env, RequestOptions())
49-
span.op = str(req.url).split("?")[0]
50-
span.peer = "%s:%s" % (req.remote_addr, req.port)
45+
with span:
46+
span.layer = Layer.Http
47+
span.component = Component.Falcon
48+
span.peer = req.remote_addr
5149

52-
span.tag(TagHttpMethod(req.method))
50+
span.tag(TagHttpMethod(method))
5351
span.tag(TagHttpURL(str(req.url)))
54-
if req.params:
55-
span.tag(TagHttpParams(params_tostring(req.params)[0:]))
5652

57-
resp = _original_falcon_api(this, env, start_response)
53+
if req.params:
54+
span.tag(TagHttpParams(','.join([k + '=' + v for k, v in req.params.items()])))
5855

59-
from falcon import ResponseOptions
56+
def _start_response(resp_status, headers):
57+
try:
58+
code, msg = resp_status.split(' ', 1)
59+
code = int(code)
60+
except Exception:
61+
code, msg = 500, 'Internal Server Error'
6062

61-
resp_obj = response.Response(ResponseOptions())
63+
if code >= 400:
64+
span.error_occurred = True
6265

63-
resp_status = parse_status(resp_obj.status)
64-
if int(resp_status[0]) >= 400:
65-
span.error_occurred = True
66+
span.tag(TagHttpStatusCode(code))
67+
span.tag(TagHttpStatusMsg(msg))
6668

67-
span.tag(TagHttpStatusCode(int(resp_status[0])))
69+
return start_response(resp_status, headers)
6870

69-
return resp
71+
try:
72+
return _original_falcon_api(this, env, _start_response)
7073

71-
def _sw_handle_exception(this: API, req, resp, ex, params):
72-
if ex is not None:
73-
entry_span = get_context().active_span()
74-
if entry_span is not None and type(entry_span) is not NoopSpan:
75-
entry_span.raised()
74+
except Exception:
75+
span.raised()
7676

77-
return _original_falcon_handle_exception(this, req, resp, ex, params)
77+
raise
7878

7979
API.__call__ = _sw_falcon_api
80-
API._handle_exception = _sw_handle_exception
81-
82-
83-
def get_headers(env):
84-
headers = {}
85-
wsgi_content_headers = frozenset(["CONTENT_TYPE", "CONTENT_LENGTH"])
86-
87-
for name, value in env.items():
88-
if name.startswith("HTTP_"):
89-
headers[name[5:].replace("_", "-")] = value
90-
91-
elif name in wsgi_content_headers:
92-
headers[name.replace("_", "-")] = value
93-
94-
return headers
95-
96-
97-
def parse_status(status_str):
98-
return status_str.split(" ") if status_str else [404, "status is empty"]

skywalking/trace/tags.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ class TagHttpStatusCode(Tag):
3434
key = 'http.status.code'
3535

3636

37+
class TagHttpStatusMsg(Tag):
38+
key = 'http.status.msg'
39+
40+
3741
class TagHttpParams(Tag):
3842
key = 'http.params'
3943

tests/plugin/sw_falcon/expected.data.yml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ segmentItems:
2323
endTime: gt 0
2424
isError: false
2525
operationId: 0
26-
operationName: http://provider:9091/users
26+
operationName: /users
2727
parentSpanId: -1
2828
peer: not null
2929
skipAnalysis: false
@@ -38,6 +38,8 @@ segmentItems:
3838
value: http://provider:9091/users
3939
- key: http.status.code
4040
value: '200'
41+
- key: http.status.msg
42+
value: OK
4143
serviceName: provider
4244
- segmentSize: 1
4345
segments:
@@ -66,7 +68,7 @@ segmentItems:
6668
endTime: gt 0
6769
isError: false
6870
operationId: 0
69-
operationName: http://0.0.0.0:9090/users
71+
operationName: /users
7072
parentSpanId: -1
7173
peer: not null
7274
skipAnalysis: false
@@ -81,4 +83,6 @@ segmentItems:
8183
value: http://0.0.0.0:9090/users
8284
- key: http.status.code
8385
value: '200'
86+
- key: http.status.msg
87+
value: OK
8488
serviceName: consumer

0 commit comments

Comments
 (0)