Skip to content

Commit f7f5aa7

Browse files
[Plugin] added pyramid plugin (#102)
* add test case Co-authored-by: kezhenxu94 <[email protected]>
1 parent 65c6e4a commit f7f5aa7

File tree

11 files changed

+377
-0
lines changed

11 files changed

+377
-0
lines changed

docs/Plugins.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,7 @@ Library | Versions | Plugin Name
1616
| [elasticsearch](https://github.com/elastic/elasticsearch-py) | 7.9.0 | `sw_elasticsearch` |
1717
| [urllib3](https://urllib3.readthedocs.io/en/latest/) | >= 1.25.9 <= 1.25.10 | `sw_urllib3` |
1818
| [sanic](https://sanic.readthedocs.io/en/latest/) | >= 20.3.0 <= 20.9.1 | `sw_sanic` |
19+
| [aiohttp](https://sanic.readthedocs.io/en/latest/) | >= 3.7.3 | `sw_aiohttp` |
20+
| [pyramid](https://trypyramid.com) | >= 1.9 | `sw_pyramid` |
1921

2022
The column `Versions` only indicates that the versions are tested, if you found the newer versions are also supported, welcome to add the newer version into the table.

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ py==1.9.0
3838
pymongo==3.11.0
3939
PyMySQL==0.10.0
4040
pyparsing==2.4.7
41+
pyramid==1.10.5
4142
pytest==6.0.1
4243
pytz==2020.1
4344
PyYAML==5.3.1

skywalking/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ class Component(Enum):
3939
Urllib3 = 7006
4040
Sanic = 7007
4141
AioHttp = 7008
42+
Pyramid = 7009
4243

4344

4445
class Layer(Enum):

skywalking/plugins/sw_pyramid.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#
2+
# Licensed to the Apache Software Foundation (ASF) under one or more
3+
# contributor license agreements. See the NOTICE file distributed with
4+
# this work for additional information regarding copyright ownership.
5+
# The ASF licenses this file to You under the Apache License, Version 2.0
6+
# (the "License"); you may not use this file except in compliance with
7+
# the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
#
17+
18+
from skywalking import Layer, Component
19+
from skywalking.trace import tags
20+
from skywalking.trace.carrier import Carrier
21+
from skywalking.trace.context import get_context
22+
from skywalking.trace.tags import Tag
23+
24+
25+
def install():
26+
from pyramid.router import Router
27+
28+
def _sw_invoke_request(self, request, *args, **kwargs):
29+
context = get_context()
30+
carrier = Carrier()
31+
32+
for item in carrier:
33+
val = request.headers.get(item.key)
34+
35+
if val is not None:
36+
item.val = val
37+
38+
with context.new_entry_span(op=request.path, carrier=carrier) as span:
39+
span.layer = Layer.Http
40+
span.component = Component.Pyramid
41+
span.peer = request.remote_host or request.remote_addr
42+
43+
span.tag(Tag(key=tags.HttpMethod, val=request.method))
44+
span.tag(Tag(key=tags.HttpUrl, val=str(request.url)))
45+
46+
resp = _invoke_request(self, request, *args, **kwargs)
47+
48+
span.tag(Tag(key=tags.HttpStatus, val=resp.status_code, overridable=True))
49+
50+
if resp.status_code >= 400:
51+
span.error_occurred = True
52+
53+
return resp
54+
55+
_invoke_request = Router.invoke_request
56+
Router.invoke_request = _sw_invoke_request
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#
2+
# Licensed to the Apache Software Foundation (ASF) under one or more
3+
# contributor license agreements. See the NOTICE file distributed with
4+
# this work for additional information regarding copyright ownership.
5+
# The ASF licenses this file to You under the Apache License, Version 2.0
6+
# (the "License"); you may not use this file except in compliance with
7+
# the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
#
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#
2+
# Licensed to the Apache Software Foundation (ASF) under one or more
3+
# contributor license agreements. See the NOTICE file distributed with
4+
# this work for additional information regarding copyright ownership.
5+
# The ASF licenses this file to You under the Apache License, Version 2.0
6+
# (the "License"); you may not use this file except in compliance with
7+
# the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
#
17+
18+
version: '2.1'
19+
20+
services:
21+
collector:
22+
extends:
23+
service: collector
24+
file: ../docker/docker-compose.base.yml
25+
26+
provider:
27+
extends:
28+
service: agent
29+
file: ../docker/docker-compose.base.yml
30+
ports:
31+
- 9091:9091
32+
volumes:
33+
- .:/app
34+
command: ['bash', '-c', 'pip install -r /app/requirements.txt && python3 /app/services/provider.py']
35+
depends_on:
36+
collector:
37+
condition: service_healthy
38+
healthcheck:
39+
test: ["CMD", "bash", "-c", "cat < /dev/null > /dev/tcp/127.0.0.1/9091"]
40+
interval: 5s
41+
timeout: 60s
42+
retries: 120
43+
44+
consumer:
45+
extends:
46+
service: agent
47+
file: ../docker/docker-compose.base.yml
48+
ports:
49+
- 9090:9090
50+
volumes:
51+
- .:/app
52+
command: ['bash', '-c', 'pip install -r /app/requirements.txt && python3 /app/services/consumer.py']
53+
depends_on:
54+
collector:
55+
condition: service_healthy
56+
provider:
57+
condition: service_healthy
58+
59+
networks:
60+
beyond:
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
#
2+
# Licensed to the Apache Software Foundation (ASF) under one or more
3+
# contributor license agreements. See the NOTICE file distributed with
4+
# this work for additional information regarding copyright ownership.
5+
# The ASF licenses this file to You under the Apache License, Version 2.0
6+
# (the "License"); you may not use this file except in compliance with
7+
# the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
#
17+
18+
segmentItems:
19+
- serviceName: provider
20+
segmentSize: 1
21+
segments:
22+
- segmentId: not null
23+
spans:
24+
- operationName: /pyramid
25+
operationId: 0
26+
parentSpanId: -1
27+
spanId: 0
28+
spanLayer: Http
29+
tags:
30+
- key: http.method
31+
value: POST
32+
- key: url
33+
value: http://provider:9091/pyramid
34+
- key: status.code
35+
value: '200'
36+
refs:
37+
- parentEndpoint: /pyramid
38+
networkAddress: provider:9091
39+
refType: CrossProcess
40+
parentSpanId: 1
41+
parentTraceSegmentId: not null
42+
parentServiceInstance: not null
43+
parentService: consumer
44+
traceId: not null
45+
startTime: gt 0
46+
endTime: gt 0
47+
componentId: 7009
48+
spanType: Entry
49+
peer: not null
50+
skipAnalysis: false
51+
- serviceName: consumer
52+
segmentSize: 1
53+
segments:
54+
- segmentId: not null
55+
spans:
56+
- operationName: /pyramid
57+
operationId: 0
58+
parentSpanId: 0
59+
spanId: 1
60+
spanLayer: Http
61+
tags:
62+
- key: http.method
63+
value: POST
64+
- key: url
65+
value: http://provider:9091/pyramid
66+
- key: status.code
67+
value: '200'
68+
startTime: gt 0
69+
endTime: gt 0
70+
componentId: 7000
71+
spanType: Exit
72+
peer: provider:9091
73+
skipAnalysis: false
74+
- operationName: /pyramid
75+
operationId: 0
76+
parentSpanId: -1
77+
spanId: 0
78+
spanLayer: Http
79+
tags:
80+
- key: http.method
81+
value: GET
82+
- key: url
83+
value: http://0.0.0.0:9090/pyramid
84+
- key: status.code
85+
value: '200'
86+
startTime: gt 0
87+
endTime: gt 0
88+
componentId: 7009
89+
spanType: Entry
90+
peer: not null
91+
skipAnalysis: false
92+
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#
2+
# Licensed to the Apache Software Foundation (ASF) under one or more
3+
# contributor license agreements. See the NOTICE file distributed with
4+
# this work for additional information regarding copyright ownership.
5+
# The ASF licenses this file to You under the Apache License, Version 2.0
6+
# (the "License"); you may not use this file except in compliance with
7+
# the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
#
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#
2+
# Licensed to the Apache Software Foundation (ASF) under one or more
3+
# contributor license agreements. See the NOTICE file distributed with
4+
# this work for additional information regarding copyright ownership.
5+
# The ASF licenses this file to You under the Apache License, Version 2.0
6+
# (the "License"); you may not use this file except in compliance with
7+
# the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
#
17+
from urllib import request
18+
from wsgiref.simple_server import make_server
19+
20+
from pyramid.config import Configurator
21+
from pyramid.response import Response
22+
23+
from skywalking import agent, config
24+
25+
26+
def index(req):
27+
data = '{"name": "whatever"}'.encode('utf8')
28+
req = request.Request(f'http://provider:9091/{req.path.lstrip("/")}')
29+
req.add_header('Content-Type', 'application/json; charset=utf-8')
30+
req.add_header('Content-Length', str(len(data)))
31+
with request.urlopen(req, data):
32+
return Response(data)
33+
34+
35+
if __name__ == '__main__':
36+
config.service_name = 'consumer'
37+
agent.start()
38+
39+
with Configurator() as config:
40+
config.add_route('pyramid', '/pyramid')
41+
config.add_view(index, route_name='pyramid')
42+
43+
app = config.make_wsgi_app()
44+
45+
server = make_server('0.0.0.0', 9090, app)
46+
47+
server.serve_forever()
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#
2+
# Licensed to the Apache Software Foundation (ASF) under one or more
3+
# contributor license agreements. See the NOTICE file distributed with
4+
# this work for additional information regarding copyright ownership.
5+
# The ASF licenses this file to You under the Apache License, Version 2.0
6+
# (the "License"); you may not use this file except in compliance with
7+
# the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
#
17+
18+
from wsgiref.simple_server import make_server
19+
20+
from pyramid.config import Configurator
21+
from pyramid.response import Response
22+
23+
from skywalking import agent, config
24+
25+
26+
def index(request):
27+
return Response('Hello World!')
28+
29+
30+
def error(request):
31+
raise Exception('Error!')
32+
33+
34+
if __name__ == '__main__':
35+
config.service_name = 'provider'
36+
config.logging_level = 'DEBUG'
37+
agent.start()
38+
39+
with Configurator() as config:
40+
config.add_route('pyramid', '/pyramid')
41+
config.add_route('error', '/error')
42+
config.add_view(index, route_name='pyramid')
43+
config.add_view(error, route_name='error')
44+
45+
app = config.make_wsgi_app()
46+
47+
server = make_server('0.0.0.0', 9091, app)
48+
49+
server.serve_forever()

0 commit comments

Comments
 (0)