a flask zipkin extension based on py_zipkin.

Related tags

Flaskflask-zipkin
Overview

flask-zipkin

a flask zipkin extension based on py_zipkin.

Installation

pip install flask_zipkin

usage

you can simply use it as other flask extensions.

from flask_zipkin import Zipkin

zipkin = Zipkin(app, sample_rate=10)
app.config['ZIPKIN_DSN'] = "http://127.0.0.1:9411/api/v1/spans"

Advance Usage

you could gen a header to pass it to other services, the downstream service will recieve this header.

@bp.route('/')
def hello():
    headers = {}
    headers.update(zipkin.create_http_headers_for_new_span())
    r = requests.get('http://localhost:5001', headers=headers)
    return r.text

flask_zipkin will use http transport by default. You could define a transport, like:

@zipkin.transport_handler
def default_handler(encoded_span):
    return requests.post(
		'your transport dsn',
        data=encoded_span,
        headers={'Content-Type': 'application/x-thrift'},
)

flask_zipkin eats all transport exception by default. You could define an exception handler, like:

@zipkin.transport_exception_handler
def default_ex_handler(ex):
    raise ex

and also, you could exempt some views, like:

@zipkin.exempt
@bp.route('/')
def hello():
    return 'hello world'

add key, value for your tracing record, like:

zipkin.update_tags(id=1, user_id=2)

app configs

ZIPKIN_DISABLE disable zipkin tracking if value is True

ZIPKIN_DSN http transport dsn: such as http://localhost:9411/api/v1/spans

Comments
  • zipkin post span with http code 400

    zipkin post span with http code 400

    zipkin-server log: Cannot decode spans due to IllegalArgumentException(Error reading List from TBinary)

    when i modify like this ,it works. 39 40 def default_handler(self, encoded_span): 41 try: 42 #body = str.encode('\x0c\x00\x00\x00\x01') + encoded_span 43 body = encoded_span

    opened by chestarss 5
  • Add child span decorator

    Add child span decorator

    This decorator aims to make easier people creating child span. Normally we have to create a span resource everytime we want to create a child span. For example:

    def some_method():
        with zipkin_span(service_name='example', span_name='some_method') as z:
            result = do_something()
            z.update_binary_annotations({'result': result})
    

    Using this decorator we can do this instead:

    @flask_zipkin.child_span
    def some_method(*args, **kwargs):
        result = do_something()
        kwargs['span'].update_binary_annotations({'result': result})  
    

    The decorated method will use flask application name as service_name and the decorated method name as span_name.

    opened by asasmoyo 3
  • repeat problem Cannot decode spans

    repeat problem Cannot decode spans

    when i modify like this ,it works. 39 40 def default_handler(self, encoded_span): 41 try: 42 #body = str.encode('\x0c\x00\x00\x00\x01') + encoded_span 43 body = encoded_span

    repeat problem #17

    opened by leolinf 2
  • encoded_span missing.

    encoded_span missing.

    Hi. I follow the instruction here but I have an error. TypeError: default_handler() missing 1 required positional argument: 'encoded_span'

    I think this is because I may lose the span for the entry service. But I actually added it. My code is as below: image

    @zipkin.transport_handler def default_handler(self, encoded_span): body = str.encode('\x0c\x00\x00\x00\x01') + encoded_span return requests.post( 'http://144.173.55.61:9411/api/v1/spans', data=body, headers={'Content-Type': 'application/x-thrift'},)

    #index #@zipkin_span(service_name='my_service', span_name='index',transport_handler=default_handler, sample_rate=100) @app.route('/') def index(): with zipkin_span( service_name='webapp', span_name='index', transport_handler=default_handler, port=9411, sample_rate=100, #0.05, # Value between 0.0 and 100.0 ): return render_template('home.html')

    Could you please help me with it?

    question 
    opened by yzexeter 2
  • 400 Bad request from handler transport

    400 Bad request from handler transport

    Here is my code server: https://onlinegdb.com/r1gZ6lnFH

    After curl localhost:8080 the console show: call zipkin transport_handler code = 400, text = Expected value at line 1 column 1 path $ reading List from json , reason = Bad Request

    How can i Fixed it. Thanks you

    opened by ndh96coder 1
  • B3 propagation header capitalization

    B3 propagation header capitalization

    even though http headers are supposed to be case-insensitive, this "Parentspanid" header as capitalized previously was failing to be picked up by downstream instrumentations. if nothing else, good for consistency

    opened by natlownes 1
  • guard against _zipkin_span not set in g

    guard against _zipkin_span not set in g

    It is possible that zipkin.logging is called before request actually has been made -- in unit tests, for example (with app.test_request_context() does not run before/after request hooks).

    opened by santtu 1
  • ZipkinError error: argument out of range

    ZipkinError error: argument out of range

    Seeing errors like

      def _after_request(self, response):
            if self._disable:
                return response
            if not hasattr(g, '_zipkin_span'):
                return response
            g._zipkin_span.stop()
            return response
        def create_http_headers_for_new_span(self):
            if self._disable:
                return dict()
    

        'b6dbb1c2b362bf51' => -5270423489115668655
    :param hex_string: the string representation of a zipkin ID
    :returns: signed int representation
    """
    return struct.unpack('q', struct.pack('Q', int(hex_string, 16)))[0]
    

    def signed_int_to_unsigned_hex(signed_int): """Converts a signed int value to a 64-bit hex string.

    opened by posix4e 0
  • docs: fix simple typo, recieve -> receive

    docs: fix simple typo, recieve -> receive

    There is a small typo in README.md.

    Should read receive rather than recieve.

    Semi-automated pull request generated by https://github.com/timgates42/meticulous/blob/master/docs/NOTE.md

    opened by timgates42 0
  • Function

    Function "_safe_header" reuse the "_headers" attribute which caused the 1st inbound trace ID to be reused forever

    In function "_safe_header", it has the following logic:

    def _safe_headers(self, headers):
        if hasattr(self, "_headers"):
            return self._headers
        self._headers = dict((k.lower(), v) for k, v in headers.__iter__())
        return self._headers
    

    If the 1st request contains "X-B3*" headers, it will assign to self._headers. Then for every inbound request after that, it reuse the _headers based on the 1st request instead of parsing from the new header. This will cause all the newly created spans are chained with the 1st trace id. Therefore for any python app which is in the middle of any process, the zipkin tracing could be incorrect.

    I am not sure if this is an actual bug, or I implemented in a wrong way which caused this issue. Please have a review, I would love to hear your reply on this.

    opened by RunzhongHuang 0
  • Function

    Function "update_tags" not working

    Hi,

    In the README.md file, there is one part of tutorial is updating the tags to the span (zipkin.update_tags(id=1, user_id=2)). I tried this in two different approach and both returns me errors.

    1, AttributeError: 'ZipkinLoggingContext' object has no attribute 'binary_annotations_dict'

    I encountered this error while I put the "update_tags" inside the route function as below (function name "index").

    from flask import Flask
    from flask_zipkin import Zipkin
    import requests
    
    app = Flask(__name__)
    app.config['ZIPKIN_DISABLE'] = False
    app.config['ZIPKIN_DSN'] = "<url>"
    zipkin = Zipkin(app)
    
    @app.route('/')
    def index():
        headers = {}
        headers.update(zipkin.create_http_headers_for_new_span())
        zipkin.update_tags(id=1, user_id=2)
        r = requests.get('<url>', headers=headers)
        return r.text, 200
    
    # Start the app server
    if __name__ == '__main__':
        app.run(debug=True, host='127.0.0.1', threaded=True)
    
    -----------------------------------------------
    
    Traceback (most recent call last):
      File "C:\<path>\venv\lib\site-packages\flask\app.py", line 2091, in __call__
        return self.wsgi_app(environ, start_response)
      File "C:\<path>\venv\lib\site-packages\flask\app.py", line 2076, in wsgi_app
        response = self.handle_exception(e)
      File "C:\<path>\venv\lib\site-packages\flask\app.py", line 2073, in wsgi_app
        response = self.full_dispatch_request()
      File "C:\<path>\venv\lib\site-packages\flask\app.py", line 1518, in full_dispatch_request
        rv = self.handle_user_exception(e)
      File "C:\<path>\venv\lib\site-packages\flask\app.py", line 1516, in full_dispatch_request
        rv = self.dispatch_request()
      File "C:\<path>\venv\lib\site-packages\flask\app.py", line 1502, in dispatch_request
        return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
      File "C:\<path>\flask-zipkin-test.py", line 26, in index
        zipkin.update_tags(id=1, user_id=2)
      File "C:\<path>\venv\lib\site-packages\flask_zipkin.py", line 152, in update_tags
        g._zipkin_span.logging_context.binary_annotations_dict.update(
    AttributeError: 'ZipkinLoggingContext' object has no attribute 'binary_annotations_dict'
    
    

    2, RuntimeError: Working outside of application context.

    This error is triggered if I put the "update_tag" function right after initialize Zipkin object.

    from flask import Flask
    from flask_zipkin import Zipkin
    import requests
    
    app = Flask(__name__)
    app.config['ZIPKIN_DISABLE'] = False
    app.config['ZIPKIN_DSN'] = "<URL>"
    zipkin = Zipkin(app)
    zipkin.update_tags(id=1, user_id=2)
    
    @app.route('/')
    def index():
        headers = {}
        headers.update(zipkin.create_http_headers_for_new_span())
        r = requests.get('<URL>', headers=headers)
        return r.text, 200
    
    # Start the app server
    if __name__ == '__main__':
        app.run(debug=True, host='127.0.0.1', threaded=True)
    
    ---------------------------------------------------
    
    Traceback (most recent call last):
      File "C:/<path>/flask-zipkin-test.py", line 10, in <module>
        zipkin.update_tags(id=1, user_id=2)
      File "C:\<path>\venv\lib\site-packages\flask_zipkin.py", line 149, in update_tags
        if all([hasattr(g, '_zipkin_span'),
      File "C:\<path>\venv\lib\site-packages\werkzeug\local.py", line 422, in __get__
        obj = instance._get_current_object()
      File "C:\<path>\venv\lib\site-packages\werkzeug\local.py", line 544, in _get_current_object
        return self.__local()  # type: ignore
      File "C:\<path>\venv\lib\site-packages\flask\globals.py", line 40, in _lookup_app_object
        raise RuntimeError(_app_ctx_err_msg)
    RuntimeError: Working outside of application context.
    

    I am not sure if I use the method in a wrong way, if yes, please let me know which part I did it wrong.

    opened by RunzhongHuang 0
  • fix span data is old

    fix span data is old

    I have two applications, one named a and the other named B. their request order is that the client requests application a, and application a requests application B again. The data sent by application B for the first time is OK, but the data sent later is old data

    opened by jiangyd 0
  • is_sampled is always False

    is_sampled is always False

    The is_sampled logic there will make it always be False. If the view function is the first span in a trace, X-B3-Sampled is not definded in headers so it is set as Fasle. And then all spans in the call chain will be False.

    I use it in two defferent flask applications and no one send trace info to server. When I changed this line to is_sampled = str(headers.get('X-B3-Sampled') or '1') == '1', it worked.

    opened by AlllenShen 0
Releases(v0.0.5)
  • v0.0.5(Dec 12, 2020)

    Mainly changes refer to https://github.com/qiajigou/flask-zipkin/pull/23 https://github.com/qiajigou/flask-zipkin/pull/27

    Contributors: @posix4e @abitrolly

    Source code(tar.gz)
    Source code(zip)
  • v0.0.3(Jul 24, 2017)

Owner
- what does qiajigou mean? - don't ask.
flask extension for integration with the awesome pydantic package

Flask-Pydantic Flask extension for integration of the awesome pydantic package with Flask. Installation python3 -m pip install Flask-Pydantic Basics v

249 Jan 06, 2023
a flask zipkin extension based on py_zipkin.

flask-zipkin a flask zipkin extension based on py_zipkin. Installation pip install flask_zipkin usage you can simply use it as other flask extensions.

39 Jul 03, 2022
Glauth management ui created with python/flask

glauth-ui Glauth-UI is a small flask web app i created to manage the minimal glauth ldap server. I created this as i wanted to use glauth for authenti

Nils Thiele 67 Nov 29, 2022
A tool for the game Politics And War. Saving players hours if searching for targets they can engage with.

A tool for the game Politics And War. Saving players hours if searching for targets they can engage with.

1 Dec 19, 2021
A Flask wrapper of Starknet state. Similar in purpose to Ganache.

Introduction A Flask wrapper of Starknet state. Similar in purpose to Ganache. Aims to mimic Starknet's Alpha testnet, but with simplified functionali

Shard Labs 159 Jan 04, 2023
Boilerplate template formwork for a Python Flask application with Mysql,Build dynamic websites rapidly.

Overview English | 简体中文 How to Build dynamic web rapidly? We choose Formwork-Flask. Formwork is a highly packaged Flask Demo. It's intergrates various

aswallz 81 May 16, 2022
A simple web application built using python flask. It can be used to scan SMEVai accounts for broken pages.

smescan A simple web application built using python flask. It can be used to scan SMEVai accounts for broken pages. Development Process Step 0: Clone

Abu Hurayra 1 Jan 30, 2022
A YouTube webscraper made with flask.

YouTube Webscraper This website is for you to check all the stats on your favorite Youtube video! Technologies Python Flask HTML CSS Pafy Contributing

Proconsulates 3 Nov 25, 2021
A template themes for phyton flask website

Flask Phyton Web template A template themes for phyton flask website

Mesin Kasir 2 Nov 29, 2021
A simple barcode and QR code generator built in Python with Flask.

✨ Komi - Barcode & QR Generator ✨ A simple barcode and QR code generator built in Python with Flask. 📑 Table of Contents Usage Installation Contribut

Bonnie Fave 2 Nov 04, 2021
Mixer -- Is a fixtures replacement. Supported Django, Flask, SqlAlchemy and custom python objects.

The Mixer is a helper to generate instances of Django or SQLAlchemy models. It's useful for testing and fixture replacement. Fast and convenient test-

Kirill Klenov 870 Jan 08, 2023
A Flask extension that enables or disables features based on configuration.

Flask FeatureFlags This is a Flask extension that adds feature flagging to your applications. This lets you turn parts of your site on or off based on

Rachel Greenfield 131 Sep 26, 2022
WebSocket support for Flask

flask-sock WebSocket support for Flask Installation pip install flask-sock Example from flask import Flask, render_template from flask_sock import Soc

Miguel Grinberg 165 Dec 27, 2022
Adds SQLAlchemy support to Flask

Flask-SQLAlchemy Flask-SQLAlchemy is an extension for Flask that adds support for SQLAlchemy to your application. It aims to simplify using SQLAlchemy

The Pallets Projects 3.9k Dec 29, 2022
A flask template with Bootstrap 4, asset bundling+minification with webpack, starter templates, and registration/authentication. For use with cookiecutter.

cookiecutter-flask A Flask template for cookiecutter. (Supports Python ≥ 3.6) See this repo for an example project generated from the most recent vers

4.3k Dec 29, 2022
Flask starter template for better structuring.

Flask Starter app Flask starter template for better structuring. use the starter plate step 1 : cloning this repo through git clone the repo git clone

Tirtharaj Sinha 1 Jul 26, 2022
The Snoopy boilerplate in flask framework for development enterprise application.

Snoopy What is snoopy! The "Snoopy" boilerplate in flask framework for development enterprise application. Motivation In my 10 years of development ex

Bekhzod 2 Sep 29, 2022
SQL Alchemy dialect for Neo4j

SQL Alchemy dialect for Neo4j This package provides the SQL dialect for Neo4j, using the official JDBC driver (the Neo4j "BI Connector" ) Installation

Beni Ben zikry 8 Jan 02, 2023
An extension to add support of Plugin in Flask.

An extension to add support of Plugin in Flask.

Doge Gui 31 May 19, 2022
A basic CRUD application built in flask using postgres as database

flask-postgres-CRUD A basic CRUD application built in flask using postgres as database Taks list Dockerfile Initial docker-compose - It is working Dat

Pablo Emídio S.S 9 Sep 25, 2022