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.
Template for a rest app with flask, flask-rest and more...

Flask REST Template About the project (some comments): The ideia behind the project is to create an useful and simple template for an rest app . Besid

107 Nov 16, 2022
Serve angular production application from python flask backend. Quick and Easy

Serve angular production application from python flask backend. Quick and Easy

mark 1 Dec 01, 2022
Another redis monitor by using flask, angular, socket.io

RedisPAPA we use redis info to monitor the redis usage. PAPA means a father who is monitoring the redis. accoding to the redis doc, it is be recommand

no13bus 393 Dec 30, 2022
Find and notify users in your Active Directory with weak passwords

Crack-O-Matic Find and notify users in your Active Directory with weak passwords. Features: Linux-based Flask-based web app Hashcat or John cracker Au

Adrian Vollmer 92 Dec 31, 2022
Neo4j Movies Example application with Flask backend using the neo4j-python-driver

Neo4j Movies Application: Quick Start This example application demonstrates how easy it is to get started with Neo4j in Python. It is a very simple we

Neo4j Examples 309 Dec 24, 2022
flask-apispec MIT flask-apispec (🥉24 · ⭐ 520) - Build and document REST APIs with Flask and apispec. MIT

flask-apispec flask-apispec is a lightweight tool for building REST APIs in Flask. flask-apispec uses webargs for request parsing, marshmallow for res

Joshua Carp 617 Dec 30, 2022
Rich implementation for Flask

Flask Rich Implements the Rich programming library with Flask. All features are toggleable, including: Better logging Colorful tracebacks Usage Import

BD103 13 Jun 06, 2022
:rocket: Generate a Postman collection from your Flask application

flask2postman A tool that creates a Postman collection from a Flask application. Install $ pip install flask2postman Example Let's say that you have a

Numberly 137 Nov 08, 2022
A Flask web application that manages student entries in a SQL database

Student Database App This is a Flask web application that manages student entries in a SQL database. Users can upload a CSV into the SQL database, mak

rebecca 1 Oct 20, 2021
docker-compose uWSGI nginx flask

docker-compose uWSGI nginx flask Note that this was tested on CentOS 7 Usage sudo yum install docker

Abdolkarim Saeedi 3 Sep 11, 2022
A Flask app template with integrated SQLAlchemy, authentication, and Bootstrap frontend

Flask-Bootstrap Flask-Bootstrap is an Flask app template for users to clone and customize as desired, as opposed to a Flask extension that you can ins

Eric S. Bullington 204 Dec 26, 2022
Live Corona statistics and information site with flask.

Flask Live Corona Info Live Corona statistics and information site with flask. Tools Flask Scrapy Matplotlib How to Run Project Download Codes git clo

Mohammad Dori 5 Jul 15, 2022
A Python chat app built with Flask that runs in the browser.

A Python chat app built with Flask that runs in the browser. Designed for local area networks that are not connected to the Internet.

Leonard Kleber 1 Dec 23, 2021
Socket.IO integration for Flask applications.

Flask-SocketIO Socket.IO integration for Flask applications. Installation You can install this package as usual with pip: pip install flask-socketio

Miguel Grinberg 4.9k Jan 02, 2023
Flask Application Structure with MongoDB

This application aims to serve as a template for APIs that intend to use mongoengine and flask-restx

Tiago Franco 5 Jun 25, 2022
Full text search for flask.

flask-msearch Installation To install flask-msearch: pip install flask-msearch # when MSEARCH_BACKEND = "whoosh" pip install whoosh blinker # when MSE

honmaple 197 Dec 29, 2022
Flask extension that takes care of API representation and authentication.

Flask-API-Utils Flask-API-Utils helps you to create APIs. It makes responses in appropriate formats, for instance, JSON. All you need to do is to retu

Marsel Mavletkulov 55 Aug 28, 2022
Source code for backpainfree.org - a Q&A platform similar to StackOverFlow

Source code for backpainfree.org - a Q&A platform similar to StackOverFlow, which is designed specifically for people with back pain problems. Users can ask questions, post answers and comments, vote

Olzhas Arystanov 8 Dec 11, 2022
Brandnew-flask is a CLI tool used to generate a powerful and mordern flask-app that supports the production environment.

Brandnew-flask is still in the initial stage and needs to be updated and improved continuously. Everyone is welcome to maintain and improve this CLI.

brandonye 4 Jul 17, 2022