Skip to content

Commit 77f5c34

Browse files
committed
ci(py): py plugins (#555)
- add--exit-code-from python-plugins - bug from _urlib - fix get_logger
1 parent efb3659 commit 77f5c34

File tree

11 files changed

+109
-44
lines changed

11 files changed

+109
-44
lines changed

.github/workflows/main.yml

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,13 +120,18 @@ jobs:
120120
- uses: actions/checkout@v2
121121
with:
122122
submodules: 'true'
123+
- name: update docker compose
124+
run: |
125+
wget "https://github.com/docker/compose/releases/latest/download/docker-compose-linux-x86_64"
126+
chmod +x docker-compose-linux-x86_64
127+
./docker-compose-linux-x86_64 version
123128
# - name: build python-plugins
124129
# run: docker-compose -f "testapps/compose.yaml" build python-plugins
125130
- name: start test environment
126-
run: docker-compose -f "testapps/compose.yaml" up python-plugins
131+
run: ./docker-compose-linux-x86_64 -f "testapps/compose.yaml" up python-plugins --exit-code-from python-plugins
127132
- name: Stop containers
128-
if: always()
129-
run: docker-compose -f "testapps/compose.yaml" down
133+
# if: always()
134+
run: ./docker-compose-linux-x86_64 -f "testapps/compose.yaml" down python-plugins
130135
Collector-agent:
131136
strategy:
132137
matrix:

plugins/PY/pinpointPy/Fastapi/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@ def __monkey_patch(*args, **kwargs):
3333
module = importlib.import_module('pinpointPy.Fastapi.' + key)
3434
monkey_patch = getattr(module, 'monkey_patch')
3535
if callable(monkey_patch):
36-
monkey_patch()
3736
get_logger().debug(
3837
f"try to install pinpointPy.Fastapi.{key} module")
38+
monkey_patch()
3939

4040

4141
def async_monkey_patch_for_pinpoint(AioRedis=True, MotorMongo=True, httpx=True):

plugins/PY/pinpointPy/Helper.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ def generatePinpointHeader(host, headers, traceId=-1):
4040
nextSeqId = pinpoint.gen_sid()
4141
pinpoint.add_context(Defines.PP_NEXT_SPAN_ID, nextSeqId, traceId)
4242
headers[Defines.PP_HEADER_PINPOINT_SPANID] = nextSeqId
43-
get_logger().debug(f'headers:{headers}')
43+
get_logger().debug(f'append PinpointHeader header:{headers}')
4444

4545

4646
def startPinpointByEnviron(environ, trace_id: int):

plugins/PY/pinpointPy/libs/_MysqlConnector/__init__.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,11 @@
2222
def monkey_patch():
2323
try:
2424
from mysql.connector.cursor import MySQLCursor, MySQLCursorPrepared
25-
from mysql.connector.cursor_cext import CMySQLCursor, CMySQLCursorPrepared
2625
from .MysqlPlugin import MysqlPlugin
27-
from .CMysqlPlugin import CMysqlPlugin
2826

2927
Interceptors = [
3028
Interceptor(MySQLCursor, 'execute', MysqlPlugin),
3129
Interceptor(MySQLCursorPrepared, 'execute', MysqlPlugin),
32-
Interceptor(CMySQLCursor, 'execute', CMysqlPlugin),
33-
Interceptor(CMySQLCursorPrepared, 'execute', CMysqlPlugin),
3430
]
3531
for interceptor in Interceptors:
3632
interceptor.enable()
@@ -41,6 +37,22 @@ def monkey_patch():
4137
if 'unittest' in sys.modules.keys():
4238
raise e
4339

40+
try:
41+
from mysql.connector.cursor_cext import CMySQLCursor, CMySQLCursorPrepared
42+
from .CMysqlPlugin import CMysqlPlugin
43+
44+
Interceptors = [
45+
Interceptor(CMySQLCursor, 'execute', CMysqlPlugin),
46+
Interceptor(CMySQLCursorPrepared, 'execute', CMysqlPlugin),
47+
]
48+
for interceptor in Interceptors:
49+
interceptor.enable()
50+
except ImportError as e:
51+
get_logger().warning(f'import _mysql_connector {e}')
52+
import sys
53+
if 'unittest' in sys.modules.keys():
54+
raise e
55+
4456

4557
__all__ = ['monkey_patch']
4658
__version__ = '0.0.3'

plugins/PY/pinpointPy/libs/_urllib/RequestPlugin.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,16 @@
2424

2525
class RequestPlugin(Common.PinTrace):
2626

27+
@staticmethod
28+
def get_url(*args, **kwargs):
29+
url = "/"
30+
if 'url' in kwargs:
31+
url = kwargs['url']
32+
else:
33+
if len(args) >= 2:
34+
url = args[1]
35+
return url
36+
2737
def __init__(self, name):
2838
super().__init__(name)
2939

@@ -41,7 +51,7 @@ def isSample(*args, **kwargs):
4151
return False, parentId, args, kwargs
4252
# pull out headers
4353
if sampled:
44-
url = args[1]
54+
url = RequestPlugin.get_url(*args, **kwargs)
4555
target = urlparse(url).netloc
4656
if pinpoint.get_context(Defines.PP_HEADER_PINPOINT_SAMPLED, parentId) == "s1":
4757
Helper.generatePinpointHeader(
@@ -60,7 +70,7 @@ def isSample(*args, **kwargs):
6070

6171
def onBefore(self, parentId, *args, **kwargs):
6272
traceId, args, kwargs = super().onBefore(parentId, *args, **kwargs)
63-
url = args[1]
73+
url = RequestPlugin.get_url(*args, **kwargs)
6474
target = urlparse(url).netloc
6575

6676
###############################################################

plugins/PY/pinpointPy/pinpoint.py

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
__logger__ = None
2929

3030

31-
def get_logger(level=logging.INFO) -> logging.Logger:
31+
def get_logger() -> logging.Logger:
3232
global __logger__
3333
if __logger__:
3434
return __logger__
@@ -42,22 +42,21 @@ def get_logger(level=logging.INFO) -> logging.Logger:
4242
file_handler = logging.FileHandler(filepath)
4343
print(filepath)
4444
file_handler.setFormatter(formatter)
45-
file_handler.setLevel(logging.DEBUG)
45+
file_handler.setLevel(level=logging.DEBUG)
4646
logger.addHandler(file_handler)
47-
elif level == logging.DEBUG:
48-
ch = logging.StreamHandler(sys.stdout)
49-
ch.setLevel(logging.DEBUG)
50-
ch.setFormatter(formatter)
51-
logger.addHandler(ch)
5247
else:
5348
ch = logging.StreamHandler(sys.stdout)
54-
ch.setLevel(logging.INFO)
49+
ch.setLevel(logging.DEBUG)
5550
ch.setFormatter(formatter)
5651
logger.addHandler(ch)
5752
__logger__ = logger
5853
return __logger__
5954

6055

56+
def _set_logger_level(level=logging.INFO):
57+
get_logger().setLevel(level)
58+
59+
6160
def app_id():
6261
global __app_id
6362
return __app_id
@@ -122,13 +121,10 @@ def set_agent(app_id_str: str, app_name_str: str, collect_agent_host: str, trac
122121
__app_id = app_id_str
123122
__app_name = app_name_str
124123
_pinpointPy.set_agent(collect_agent_host, trace_limit)
125-
get_logger().setLevel(log_level)
126124
if log_level == logging.DEBUG:
127125
def debug_func(msg: str):
128126
get_logger().debug(msg=msg)
129127
_pinpointPy.enable_debug(debug_func)
130-
global __logger__
131-
__logger__ = None
132-
get_logger(log_level)
128+
_set_logger_level(log_level)
133129
get_logger().debug(
134130
f"appid:{app_id_str} appname:{app_name_str} collector_agent:{collect_agent_host} trace_limit:{trace_limit} log_level:{log_level}")

plugins/PY/requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ bottle==0.12.25
22
fastapi==0.104.1
33
flask==3.0.0
44
httpx==0.25.1
5-
mysql-connector-python==8.2.0
5+
mysql-connector-python==8.0.31
66
pymongo==4.6.0
77
PyMySQL==1.1.0
88
redis==5.0.1

testapps/backend/main.py

Lines changed: 56 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from fastapi import FastAPI, Request, Response, Depends, HTTPException
22
from starlette.middleware import Middleware
3-
from pinpointPy.Fastapi import PinPointMiddleWare, async_monkey_patch_for_pinpoint
4-
from pinpointPy import set_agent
3+
from pinpointPy.Fastapi import PinPointMiddleWare, async_monkey_patch_for_pinpoint, use_starlette_context
4+
from pinpointPy import set_agent, monkey_patch_for_pinpoint
55
from sqlalchemy.orm import Session
66
from starlette_context.middleware import ContextMiddleware
77
import aioredis
@@ -33,9 +33,11 @@ async def dispatch(self, request: Request, call_next):
3333
Middleware(UserMiddleWare)
3434
]
3535

36+
use_starlette_context()
37+
monkey_patch_for_pinpoint()
3638
async_monkey_patch_for_pinpoint()
3739

38-
set_agent("cd.dev.test.py.backend", "cd.dev.test.py.backend", 'tcp:dev-collector:10000')
40+
set_agent("cd.dev.test.py.backends", "cd.dev.test.backends", 'tcp:dev-collector:10000')
3941

4042

4143
@asynccontextmanager
@@ -67,16 +69,48 @@ async def db_session_middleware(request: Request, call_next):
6769
return response
6870

6971

70-
def get_db(request: Request):
71-
return request.state.db
72-
73-
7472
@app.get("/")
7573
async def root():
7674
return {"message": "Hello World"}
7775

7876

79-
@app.get("/test-redis/set/{uid}", tags=["redis"])
77+
@app.get("/test-requests", tags=['sync-libraries'])
78+
async def test_requests(request: Request, url='http://www.example.com'):
79+
import requests
80+
x = requests.get(url)
81+
return {"response": x.status_code}
82+
83+
84+
@app.get("/test-mysql-connector", tags=['sync-libraries'])
85+
async def test_mysql_connector(request: Request):
86+
import datetime
87+
import mysql.connector
88+
89+
cnx = mysql.connector.connect(
90+
user='root',
91+
password='password',
92+
host='dev-mysql',
93+
database='employees')
94+
cursor = cnx.cursor()
95+
96+
query = ("SELECT first_name, last_name, hire_date FROM employees "
97+
"WHERE hire_date BETWEEN %s AND %s")
98+
99+
hire_start = datetime.date(1999, 1, 1)
100+
hire_end = datetime.date(1999, 12, 31)
101+
102+
cursor.execute(query, (hire_start, hire_end))
103+
104+
for (first_name, last_name, hire_date) in cursor:
105+
print("{}, {} was hired on {:%d %b %Y}".format(
106+
last_name, first_name, hire_date))
107+
108+
cursor.close()
109+
cnx.close()
110+
return {"response": 200}
111+
112+
113+
@app.get("/test-redis/set/{uid}", tags=["aioredis"])
80114
async def test_redis(uid: str = "default"):
81115
await redis.set(uid, "50fdf310-7d3b-11ee-b962-0242ac120002", ex=1)
82116
in_value = await redis.get(uid)
@@ -91,45 +125,53 @@ async def test_httpx(request: Request, url='http://www.example.com/'):
91125
return {"response": response.status_code}
92126

93127

128+
@app.get("/httpx/backend", tags=["httpx"])
129+
async def test_httpx_backend(request: Request, url='http://backend:8000/'):
130+
requests_client = request.app.requests_client
131+
print(request.headers)
132+
response = await requests_client.get(url)
133+
return {"response": response.status_code}
134+
135+
94136
@app.get("/httpx-self/", tags=["httpx"])
95-
async def test_httpx(request: Request):
137+
async def test_httpx_self(request: Request):
96138
requests_client = request.app.requests_client
97139
response = await requests_client.get('http://127.0.0.1:8000/httpx/example')
98140
return {"response": response.status_code}
99141

100142
# thanks guide from https://fastapi.tiangolo.com/tutorial/sql-databases/
101143

102144

103-
@app.post("/users/", response_model=schemas.User, tags=["mysql"])
145+
@app.post("/users/", response_model=schemas.User, tags=["sqlalchemy"])
104146
def create_user(user: schemas.UserCreate, db: Session = Depends(get_db)):
105147
db_user = crud.get_user_by_email(db, email=user.email)
106148
if db_user:
107149
raise HTTPException(status_code=400, detail="Email already registered")
108150
return crud.create_user(db=db, user=user)
109151

110152

111-
@app.get("/users/", response_model=List[schemas.User], tags=["mysql"])
153+
@app.get("/users/", response_model=List[schemas.User], tags=["sqlalchemy"])
112154
def read_users(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
113155
users = crud.get_users(db, skip=skip, limit=limit)
114156
return users
115157

116158

117-
@app.get("/users/{user_id}", response_model=schemas.User, tags=["mysql"])
159+
@app.get("/users/{user_id}", response_model=schemas.User, tags=["sqlalchemy"])
118160
def read_user(user_id: int, db: Session = Depends(get_db)):
119161
db_user = crud.get_user(db, user_id=user_id)
120162
if db_user is None:
121163
raise HTTPException(status_code=404, detail="User not found")
122164
return db_user
123165

124166

125-
@app.post("/users/{user_id}/items/", response_model=schemas.Item, tags=["mysql"])
167+
@app.post("/users/{user_id}/items/", response_model=schemas.Item, tags=["sqlalchemy"])
126168
def create_item_for_user(
127169
user_id: int, item: schemas.ItemCreate, db: Session = Depends(get_db)
128170
):
129171
return crud.create_user_item(db=db, item=item, user_id=user_id)
130172

131173

132-
@app.get("/items/", response_model=List[schemas.Item], tags=["mysql"])
174+
@app.get("/items/", response_model=List[schemas.Item], tags=["sqlalchemy"])
133175
def read_items(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
134176
items = crud.get_items(db, skip=skip, limit=limit)
135177
return items

testapps/backend/requirements.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,6 @@ SQLAlchemy==2.0.23
66
starlette
77
starlette_context
88
uvicorn
9-
pymysql
9+
pymysql
10+
requests
11+
mysql-connector-python==8.0.31

testapps/fastapi/main.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,6 @@ async def db_session_middleware(request: Request, call_next):
6969
return response
7070

7171

72-
def get_db(request: Request):
73-
return request.state.db
74-
75-
7672
@app.get("/")
7773
async def root():
7874
return {"message": "Hello World"}

testapps/fastapi/requirements.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,6 @@ SQLAlchemy==2.0.23
66
starlette
77
starlette_context
88
uvicorn
9-
pymysql
9+
pymysql
10+
requests
11+
mysql-connector-python==8.0.31

0 commit comments

Comments
 (0)