This is an automated email from the ASF dual-hosted git repository.

wusheng pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/skywalking-showcase.git


The following commit(s) were added to refs/heads/main by this push:
     new cb76fe4  Update Python agent to v1.2.0 with forking support and PVM 
metrics (#228)
cb76fe4 is described below

commit cb76fe4b6bfbf946ea6d827ae6129433fcd7a3a1
Author: chani <[email protected]>
AuthorDate: Mon Jan 19 20:07:58 2026 +0900

    Update Python agent to v1.2.0 with forking support and PVM metrics (#228)
---
 services/recommendation-service/Dockerfile       | 38 ++++++-------
 services/recommendation-service/requirements.txt | 17 ++++++
 services/recommendation-service/src/app.py       | 69 ++++++++++++------------
 3 files changed, 68 insertions(+), 56 deletions(-)

diff --git a/services/recommendation-service/Dockerfile 
b/services/recommendation-service/Dockerfile
index 40f36fa..ba69280 100644
--- a/services/recommendation-service/Dockerfile
+++ b/services/recommendation-service/Dockerfile
@@ -1,30 +1,26 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
 #
-#   http://www.apache.org/licenses/LICENSE-2.0
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
 #
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
 #
-
 # @feature: python-agent;
-FROM apache/skywalking-python:0.7.0-grpc-py3.9
+FROM apache/skywalking-python:1.2.0-grpc-py3.10-slim
 
 WORKDIR /workspace
-
 COPY requirements.txt .
-
 RUN pip install -r requirements.txt
-
 COPY src .
-
-CMD python app.py
+# Enable forking support with -p flag for gunicorn workers
+# PVM meter reporter is enabled by default in v1.0.0+
+CMD ["run", "-p", "gunicorn", "-w", "2", "-b", "0.0.0.0:80", "app:app"]
diff --git a/services/recommendation-service/requirements.txt 
b/services/recommendation-service/requirements.txt
index 3a4df99..57f62f5 100644
--- a/services/recommendation-service/requirements.txt
+++ b/services/recommendation-service/requirements.txt
@@ -1,2 +1,19 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
 Flask==2.3.2
 requests==2.26.0
+gunicorn==21.2.0
diff --git a/services/recommendation-service/src/app.py 
b/services/recommendation-service/src/app.py
index f43df06..250bbc3 100644
--- a/services/recommendation-service/src/app.py
+++ b/services/recommendation-service/src/app.py
@@ -17,50 +17,49 @@
 import os
 
 import requests
+from flask import Flask, jsonify, request
 
-if __name__ == '__main__':
-    from flask import Flask, jsonify, request
-
-    app = Flask(__name__)
+app = Flask(__name__)
 
 
-    @app.route('/health', methods=['GET'])
-    def health():
-        return 'OK'
[email protected]('/health', methods=['GET'])
+def health():
+    return 'OK'
 
 
-    @app.route('/rcmd', methods=['GET'])
-    def application():
-        headers = {}
-        for key in [
-            'x-b3-traceid',
-            'x-b3-spanid',
-            'x-b3-parentspanid',
-            'x-b3-sampled',
-            'x-b3-flags',
-        ]:
-            val = request.headers.get(key)
-            if val is not None:
-                headers[key] = request.headers[key]
[email protected]('/rcmd', methods=['GET'])
+def application():
+    headers = {}
+    for key in [
+        'x-b3-traceid',
+        'x-b3-spanid',
+        'x-b3-parentspanid',
+        'x-b3-sampled',
+        'x-b3-flags',
+    ]:
+        val = request.headers.get(key)
+        if val is not None:
+            headers[key] = request.headers[key]
 
-        songsResponse = requests.get('http://songs/songs', headers=headers)
-        songs = songsResponse.json()
-        ratingResponse = requests.get('http://rating/rating', headers=headers)
-        ratings = ratingResponse.json()
+    songsResponse = requests.get('http://songs/songs', headers=headers)
+    songs = songsResponse.json()
+    ratingResponse = requests.get('http://rating/rating', headers=headers)
+    ratings = ratingResponse.json()
 
-        # combine ratings to songs
-        ratings_dict = {}
-        for rating_data in ratings:
-            song_id = rating_data['id']
-            ratings_dict[song_id] = rating_data['rating']
-        for song_data in songs:
-            song_id = song_data['id']
-            rating = ratings_dict.get(song_id)
-            if rating is not None:
-                song_data['rating'] = rating
+    # combine ratings to songs
+    ratings_dict = {}
+    for rating_data in ratings:
+        song_id = rating_data['id']
+        ratings_dict[song_id] = rating_data['rating']
+    for song_data in songs:
+        song_id = song_data['id']
+        rating = ratings_dict.get(song_id)
+        if rating is not None:
+            song_data['rating'] = rating
 
-        return jsonify(songs)
+    return jsonify(songs)
 
 
+if __name__ == '__main__':
     PORT = os.getenv('PORT', 80)
     app.run(host='0.0.0.0', port=PORT)

Reply via email to