Giter Site home page Giter Site logo

thrift-tools's Introduction

thrift-tools Build Status Coverage Status PyPI version

Table of Contents

tl;dr

thrift-tools is a library and a set of tools to introspect Apache Thrift traffic.

Installing

You can install thrift-tools via pip:

$ pip install thrift-tools

Or run it from source (if you have the dependencies installed, see below):

$ git clone ...
$ cd thrift-tools
$ sudo FROM_SOURCE=1 bin/thrift-tool --iface=eth0 --port 9091 dump --show-all --pretty
...
$ FROM_SOURCE=1 bin/thrift-tool --port 9090 \
    --pcap-file thrift_tools/tests/resources/calc-service-binary.pcap \
    dump --show-all --pretty --color \
    --idl-file=thrift_tools/tests/resources/tutorial.thrift

Tools

thrift-tool can be used in interactive mode to analyze live thrift messages:

$ sudo thrift-tool --iface eth0 --port 9091 dump --show-all --pretty
[00:39:42:850848] 10.1.8.7:49858 -> 10.1.2.20:3636: method=dosomething, type=call, seqid=1120
header: ()
fields: [   (   'struct',
        1,
        [   ('string', 1, 'something to do'),
            ('i32', 3, 0),
            (   'struct',
                9,
                [   ('i32', 3, 2),
                    ('i32', 14, 0),
                    ('i32', 16, 0),
                    ('i32', 18, 25)])])]
------>[00:39:42:856204] 10.1.2.20:3636 -> 10.1.8.7:49858: method=dosomething, type=reply, seqid=1120
        header: ()
        fields: [   (   'struct',
        0,
        [   ('string', 1, 'did something'),
            ('string', 2, 'did something else'),
            ('string', 3, 'did some other thing'),
            ('string', 4, 'did the last thing'),
            ('i32', 6, 3),
            ('i32', 7, 11),
            ('i32', 8, 0),
            ('i32', 9, 0),
            ('list', 10, [0]),
...

Alternatively, offline pcap files may be introspected:

$ sudo thrift-tool --port 9091 --pcap-file /path/to/myservice.pcap dump
...

Note that you still need to set the right port.

If you are using Finagle, try something like:

$ sudo thrift-tool --iface eth0 --port 9091 dump --show-all --pretty --finagle-thrift
...

JSON output is available for easy filtering & querying via jq. For instance, you can enumerate all the IPs calling the method 'search' via:

$ sudo thrift-tool --port 3030 dump --unpaired --json | jq 'select(.method == "search" and .type == "call") | .src'
"10.1.18.5:48534"
"10.1.60.2:52008"
"10.1.10.27:49856"
"10.1.23.24:48116"
"10.1.26.7:60462"
"10.1.11.10:41895"
"10.1.15.13:35285"
"10.1.7.17:39759"
"10.1.1.19:35481"
...

Gathering per method latency stats is available via the stats command:

$ sudo thrift-tool --port 6666 stats --count 100
method      count         avg         min         max         p90         p95         p99        p999
--------  -------  ----------  ----------  ----------  ----------  ----------  ----------  ----------
search2        61  0.00860996  0.00636292  0.0188479   0.010778    0.015192    0.0174422   0.0187074
doc            39  0.00134846  0.00099802  0.00274897  0.00177183  0.00199242  0.00256242  0.00273031
287 unmatched calls

You can also specify .thrift file for nicer output:

$ sudo thrift-tool --port 9091 dump --show-all --pretty --color --idl-file /path/to/myidl.thrift
...

To list all the available options:

$ thrift-tool --help

Note that for servers with high throughput (i.e.: > couple Ks packets per second), it might be hard for thrift-tools to keep up because start of message detection is a bit expensive (and you can only go so fast with Python). For these cases, you are better off saving a pcap file (i.e.: via tcpdump) and then post-processing it, i.e.:

$ tcpdump -nn -t port 3030 -w dump.pcap
$ sudo thrift-tool --port 3030 --pcap-file dump.pcap stats --count 40000
method      count         avg         min         max         p90         p95         p99        p999
--------  -------  ----------  ----------  ----------  ----------  ----------  ----------  ----------
resize      40000  0.00850996  0.00336091  0.0101364   0.008071    0.009132    0.009890   0.01005665

Library

To use thrift-tools from another (Python) application, you can import it via:

from thrift_tools.message_sniffer import MessageSnifferOptions, MessageSniffer

options = MessageSnifferOptions(
    iface='eth0',
    port='3636',
    ip=None,                         # include msgs from all IPs
    pcap_file=None,                  # don't read from a pcap file, live sniff
    protocol=None,                   # auto detect protocol
    finagle_thrift=False,            # apache thrift (not twitter's finagle)
    read_values=True,                # read the values of each msg/struct
    max_queued=20000,                # decent sized queue
    max_message_size=2000,           # 2k messages to keep mem usage frugal
    debug=False                      # don't print parsing errors, etc
    )

def printer(timestamp, src, dst, msg):
  print '%s %s %s %s' % (timestamp, src, dst, msg)

message_sniffer = MessageSniffer(options, printer)

# loop forever
message_sniffer.join()

Of if you want to use a pcap file:

options = MessageSnifferOptions(
    iface='eth0',
    port='3636',
    ip=None,
    pcap_file="/tmp/myservice.pcap",
    protocol=None,
    finagle_thrift=False,
    read_values=True,
    max_queued=20000,
    max_message_size=2000,
    debug=False
    )

...

If you want to filter messages for specific IPs:

options = MessageSnifferOptions(
    iface='eth0',
    port='3636',
    ip=['172.16.24.3', '172.16.24.4'],  # ignores everyone else
    pcap_file="/tmp/myservice.pcap",
    protocol=None,
    finagle_thrift=False,
    read_values=True,
    max_queued=20000,
    max_message_size=2000,
    debug=False
    )

...

See examples/ for more ways to use this library!

Tests

To run the tests:

$ python setup.py nosetests

thrift-tools's People

Contributors

bancek avatar jparise avatar rgs1 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

thrift-tools's Issues

ImportError: cannot import name 'send' from partially initialized module 'scapy.sendrecv' (most likely due to a circular import)

thrift-tool --port 9090 --pcap-file ~/share.pcap dump --show-all --pretty

Traceback (most recent call last):
File "/Users/hq/Library/Python/3.8/bin/thrift-tool", line 11, in
from thrift_tools.tool import main
File "/Users/hq/Library/Python/3.8/lib/python/site-packages/thrift_tools/tool.py", line 13, in
from .message_sniffer import MessageSnifferOptions, MessageSniffer
File "/Users/hq/Library/Python/3.8/lib/python/site-packages/thrift_tools/message_sniffer.py", line 8, in
from .sniffer import Sniffer
File "/Users/hq/Library/Python/3.8/lib/python/site-packages/thrift_tools/sniffer.py", line 13, in
from scapy.sendrecv import sniff
File "/Users/hq/Library/Python/3.8/lib/python/site-packages/scapy/sendrecv.py", line 61, in
import scapy.route # noqa: F401
File "/Users/hq/Library/Python/3.8/lib/python/site-packages/scapy/route.py", line 218, in
conf.route = Route()
File "/Users/hq/Library/Python/3.8/lib/python/site-packages/scapy/route.py", line 37, in init
self.resync()
File "/Users/hq/Library/Python/3.8/lib/python/site-packages/scapy/route.py", line 45, in resync
from scapy.arch import read_routes
File "/Users/hq/Library/Python/3.8/lib/python/site-packages/scapy/arch/init.py", line 124, in
from scapy.arch.bpf.supersocket import * # noqa F403
File "/Users/hq/Library/Python/3.8/lib/python/site-packages/scapy/arch/bpf/supersocket.py", line 27, in
from scapy.layers.l2 import Loopback
File "/Users/hq/Library/Python/3.8/lib/python/site-packages/scapy/layers/l2.py", line 17, in
from scapy.ansmachine import AnsweringMachine
File "/Users/hq/Library/Python/3.8/lib/python/site-packages/scapy/ansmachine.py", line 20, in
from scapy.sendrecv import send, sniff
ImportError: cannot import name 'send' from partially initialized module 'scapy.sendrecv' (most likely due to a circular import) (/Users/hq/Library/Python/3.8/lib/python/site-packages/scapy/sendrecv.py)

Does it support generating thrift files

Hello, author
Whether thrift tools can generate the IDL file corresponding to thrift through the listening process only needs to ensure that the type and order are correct, and the field names are named in order.

Unable to run on Mac OS

$ thrift-tool 
Traceback (most recent call last):
  File "/usr/local/bin/thrift-tool", line 11, in <module>
    from thrift_tools.tool import main
  File "/Library/Python/2.7/site-packages/thrift_tools/tool.py", line 13, in <module>
    from .message_sniffer import MessageSnifferOptions, MessageSniffer
  File "/Library/Python/2.7/site-packages/thrift_tools/message_sniffer.py", line 8, in <module>
    from .sniffer import Sniffer
  File "/Library/Python/2.7/site-packages/thrift_tools/sniffer.py", line 13, in <module>
    from scapy.sendrecv import sniff
  File "/Library/Python/2.7/site-packages/scapy/sendrecv.py", line 13, in <module>
    import arch
  File "/Library/Python/2.7/site-packages/scapy/arch/__init__.py", line 75, in <module>
    from bsd import *
  File "/Library/Python/2.7/site-packages/scapy/arch/bsd.py", line 12, in <module>
    from unix import *
  File "/Library/Python/2.7/site-packages/scapy/arch/unix.py", line 20, in <module>
    from pcapdnet import *
  File "/Library/Python/2.7/site-packages/scapy/arch/pcapdnet.py", line 30, in <module>
    import pcapy as pcap
ImportError: No module named pcapy

while It was installed successfully

$ sudo pip install thrift-tools
Collecting thrift-tools
  Downloading thrift-tools-0.0.3.tar.gz
Collecting ansicolors (from thrift-tools)
  Downloading ansicolors-1.0.2.tar.gz
Collecting dpkt (from thrift-tools)
  Downloading dpkt-1.9.1-py2-none-any.whl (136kB)
    100% |################################| 139kB 632kB/s 
Collecting scapy==2.3.1 (from thrift-tools)
  Downloading scapy-2.3.1.zip (1.1MB)
    100% |################################| 1.1MB 565kB/s 
Collecting thrift==0.9.2 (from thrift-tools)
  Downloading thrift-0.9.2.tar.gz
Requirement already satisfied (use --upgrade to upgrade): tabulate in /Library/Python/2.7/site-packages (from thrift-tools)
Installing collected packages: thrift, scapy, dpkt, ansicolors, thrift-tools
  Found existing installation: thrift 0.9.3
    Uninstalling thrift-0.9.3:
      Successfully uninstalled thrift-0.9.3
  Running setup.py install for thrift
    building 'thrift.protocol.fastbinary' extension
    cc -fno-strict-aliasing -fno-common -dynamic -arch x86_64 -arch i386 -g -Os -pipe -fno-common -fno-strict-aliasing -fwrapv -DENABLE_DTRACE -DMACOSX -DNDEBUG -Wall -Wstrict-prototypes -Wshorten-64-to-32 -DNDEBUG -g -fwrapv -Os -Wall -Wstrict-prototypes -DENABLE_DTRACE -arch x86_64 -arch i386 -pipe -I/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7 -c src/protocol/fastbinary.c -o build/temp.macosx-10.10-intel-2.7/src/protocol/fastbinary.o
    src/protocol/fastbinary.c:114:11: warning: 'ntohll' macro redefined [-Wmacro-redefined]
    #  define ntohll(n) ( (((unsigned long long)ntohl(n)) << 32) + ntohl(n >> 32) )
              ^
    /usr/include/sys/_endian.h:140:9: note: previous definition is here
    #define ntohll(x)       __DARWIN_OSSwapInt64(x)
            ^
    src/protocol/fastbinary.c:115:11: warning: 'htonll' macro redefined [-Wmacro-redefined]
    #  define htonll(n) ( (((unsigned long long)htonl(n)) << 32) + htonl(n >> 32) )
              ^
    /usr/include/sys/_endian.h:141:9: note: previous definition is here
    #define htonll(x)       __DARWIN_OSSwapInt64(x)
            ^
    src/protocol/fastbinary.c:226:24: warning: implicit conversion loses integer precision: 'long' to 'TType' (aka 'enum TType') [-Wshorten-64-to-32]
      dest->element_type = PyInt_AsLong(PyTuple_GET_ITEM(typeargs, 0));
                         ~ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    src/protocol/fastbinary.c:227:7: warning: comparison of constant -1 with expression of type 'TType' (aka 'enum TType') is always false [-Wtautological-constant-out-of-range-compare]
      if (INT_CONV_ERROR_OCCURRED(dest->element_type)) {
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    src/protocol/fastbinary.c:124:43: note: expanded from macro 'INT_CONV_ERROR_OCCURRED'
    #define INT_CONV_ERROR_OCCURRED(v) ( ((v) == -1) && PyErr_Occurred() )
                                          ~~~ ^  ~~
    src/protocol/fastbinary.c:243:16: warning: implicit conversion loses integer precision: 'long' to 'TType' (aka 'enum TType') [-Wshorten-64-to-32]
      dest->ktag = PyInt_AsLong(PyTuple_GET_ITEM(typeargs, 0));
                 ~ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    src/protocol/fastbinary.c:244:7: warning: comparison of constant -1 with expression of type 'TType' (aka 'enum TType') is always false [-Wtautological-constant-out-of-range-compare]
      if (INT_CONV_ERROR_OCCURRED(dest->ktag)) {
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    src/protocol/fastbinary.c:124:43: note: expanded from macro 'INT_CONV_ERROR_OCCURRED'
    #define INT_CONV_ERROR_OCCURRED(v) ( ((v) == -1) && PyErr_Occurred() )
                                          ~~~ ^  ~~
    src/protocol/fastbinary.c:248:16: warning: implicit conversion loses integer precision: 'long' to 'TType' (aka 'enum TType') [-Wshorten-64-to-32]
      dest->vtag = PyInt_AsLong(PyTuple_GET_ITEM(typeargs, 2));
                 ~ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    src/protocol/fastbinary.c:249:7: warning: comparison of constant -1 with expression of type 'TType' (aka 'enum TType') is always false [-Wtautological-constant-out-of-range-compare]
      if (INT_CONV_ERROR_OCCURRED(dest->vtag)) {
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    src/protocol/fastbinary.c:124:43: note: expanded from macro 'INT_CONV_ERROR_OCCURRED'
    #define INT_CONV_ERROR_OCCURRED(v) ( ((v) == -1) && PyErr_Occurred() )
                                          ~~~ ^  ~~
    src/protocol/fastbinary.c:281:15: warning: implicit conversion loses integer precision: 'long' to 'int' [-Wshorten-64-to-32]
      dest->tag = PyInt_AsLong(PyTuple_GET_ITEM(spec_tuple, 0));
                ~ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    src/protocol/fastbinary.c:286:16: warning: implicit conversion loses integer precision: 'long' to 'TType' (aka 'enum TType') [-Wshorten-64-to-32]
      dest->type = PyInt_AsLong(PyTuple_GET_ITEM(spec_tuple, 1));
                 ~ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    src/protocol/fastbinary.c:287:7: warning: comparison of constant -1 with expression of type 'TType' (aka 'enum TType') is always false [-Wtautological-constant-out-of-range-compare]
      if (INT_CONV_ERROR_OCCURRED(dest->type)) {
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    src/protocol/fastbinary.c:124:43: note: expanded from macro 'INT_CONV_ERROR_OCCURRED'
    #define INT_CONV_ERROR_OCCURRED(v) ( ((v) == -1) && PyErr_Occurred() )
                                          ~~~ ^  ~~
    src/protocol/fastbinary.c:489:22: warning: implicit conversion loses integer precision: 'Py_ssize_t' (aka 'long') to 'int32_t' (aka 'int') [-Wshorten-64-to-32]
        writeI32(output, len);
        ~~~~~~~~         ^~~
    src/protocol/fastbinary.c:740:7: warning: comparison of constant -1 with expression of type 'TType' (aka 'enum TType') is always false [-Wtautological-constant-out-of-range-compare]
      if (INT_CONV_ERROR_OCCURRED(got)) {
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
    src/protocol/fastbinary.c:124:43: note: expanded from macro 'INT_CONV_ERROR_OCCURRED'
    #define INT_CONV_ERROR_OCCURRED(v) ( ((v) == -1) && PyErr_Occurred() )
                                          ~~~ ^  ~~
    src/protocol/fastbinary.c:787:15: warning: comparison of constant -1 with expression of type 'TType' (aka 'enum TType') is always false [-Wtautological-constant-out-of-range-compare]
        if (etype == -1) {
            ~~~~~ ^  ~~
    src/protocol/fastbinary.c:809:15: warning: comparison of constant -1 with expression of type 'TType' (aka 'enum TType') is always false [-Wtautological-constant-out-of-range-compare]
        if (ktype == -1) {
            ~~~~~ ^  ~~
    src/protocol/fastbinary.c:814:15: warning: comparison of constant -1 with expression of type 'TType' (aka 'enum TType') is always false [-Wtautological-constant-out-of-range-compare]
        if (vtype == -1) {
            ~~~~~ ^  ~~
    src/protocol/fastbinary.c:836:16: warning: comparison of constant -1 with expression of type 'TType' (aka 'enum TType') is always false [-Wtautological-constant-out-of-range-compare]
          if (type == -1) {
              ~~~~ ^  ~~
    src/protocol/fastbinary.c:875:22: warning: implicit conversion loses integer precision: 'Py_ssize_t' (aka 'long') to 'int' [-Wshorten-64-to-32]
      int spec_seq_len = PyTuple_Size(spec_seq);
          ~~~~~~~~~~~~   ^~~~~~~~~~~~~~~~~~~~~~
    src/protocol/fastbinary.c:888:14: warning: comparison of constant -1 with expression of type 'TType' (aka 'enum TType') is always false [-Wtautological-constant-out-of-range-compare]
        if (type == -1) {
            ~~~~ ^  ~~
    src/protocol/fastbinary.c:1008:33: warning: implicit conversion loses integer precision: 'Py_ssize_t' (aka 'long') to 'int' [-Wshorten-64-to-32]
        if (!readBytes(input, &buf, len)) {
             ~~~~~~~~~              ^~~
    20 warnings generated.
    src/protocol/fastbinary.c:114:11: warning: 'ntohll' macro redefined [-Wmacro-redefined]
    #  define ntohll(n) ( (((unsigned long long)ntohl(n)) << 32) + ntohl(n >> 32) )
              ^
    /usr/include/sys/_endian.h:140:9: note: previous definition is here
    #define ntohll(x)       __DARWIN_OSSwapInt64(x)
            ^
    src/protocol/fastbinary.c:115:11: warning: 'htonll' macro redefined [-Wmacro-redefined]
    #  define htonll(n) ( (((unsigned long long)htonl(n)) << 32) + htonl(n >> 32) )
              ^
    /usr/include/sys/_endian.h:141:9: note: previous definition is here
    #define htonll(x)       __DARWIN_OSSwapInt64(x)
            ^
    src/protocol/fastbinary.c:227:7: warning: comparison of constant -1 with expression of type 'TType' (aka 'enum TType') is always false [-Wtautological-constant-out-of-range-compare]
      if (INT_CONV_ERROR_OCCURRED(dest->element_type)) {
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    src/protocol/fastbinary.c:124:43: note: expanded from macro 'INT_CONV_ERROR_OCCURRED'
    #define INT_CONV_ERROR_OCCURRED(v) ( ((v) == -1) && PyErr_Occurred() )
                                          ~~~ ^  ~~
    src/protocol/fastbinary.c:244:7: warning: comparison of constant -1 with expression of type 'TType' (aka 'enum TType') is always false [-Wtautological-constant-out-of-range-compare]
      if (INT_CONV_ERROR_OCCURRED(dest->ktag)) {
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    src/protocol/fastbinary.c:124:43: note: expanded from macro 'INT_CONV_ERROR_OCCURRED'
    #define INT_CONV_ERROR_OCCURRED(v) ( ((v) == -1) && PyErr_Occurred() )
                                          ~~~ ^  ~~
    src/protocol/fastbinary.c:249:7: warning: comparison of constant -1 with expression of type 'TType' (aka 'enum TType') is always false [-Wtautological-constant-out-of-range-compare]
      if (INT_CONV_ERROR_OCCURRED(dest->vtag)) {
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    src/protocol/fastbinary.c:124:43: note: expanded from macro 'INT_CONV_ERROR_OCCURRED'
    #define INT_CONV_ERROR_OCCURRED(v) ( ((v) == -1) && PyErr_Occurred() )
                                          ~~~ ^  ~~
    src/protocol/fastbinary.c:287:7: warning: comparison of constant -1 with expression of type 'TType' (aka 'enum TType') is always false [-Wtautological-constant-out-of-range-compare]
      if (INT_CONV_ERROR_OCCURRED(dest->type)) {
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    src/protocol/fastbinary.c:124:43: note: expanded from macro 'INT_CONV_ERROR_OCCURRED'
    #define INT_CONV_ERROR_OCCURRED(v) ( ((v) == -1) && PyErr_Occurred() )
                                          ~~~ ^  ~~
    src/protocol/fastbinary.c:740:7: warning: comparison of constant -1 with expression of type 'TType' (aka 'enum TType') is always false [-Wtautological-constant-out-of-range-compare]
      if (INT_CONV_ERROR_OCCURRED(got)) {
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
    src/protocol/fastbinary.c:124:43: note: expanded from macro 'INT_CONV_ERROR_OCCURRED'
    #define INT_CONV_ERROR_OCCURRED(v) ( ((v) == -1) && PyErr_Occurred() )
                                          ~~~ ^  ~~
    src/protocol/fastbinary.c:787:15: warning: comparison of constant -1 with expression of type 'TType' (aka 'enum TType') is always false [-Wtautological-constant-out-of-range-compare]
        if (etype == -1) {
            ~~~~~ ^  ~~
    src/protocol/fastbinary.c:809:15: warning: comparison of constant -1 with expression of type 'TType' (aka 'enum TType') is always false [-Wtautological-constant-out-of-range-compare]
        if (ktype == -1) {
            ~~~~~ ^  ~~
    src/protocol/fastbinary.c:814:15: warning: comparison of constant -1 with expression of type 'TType' (aka 'enum TType') is always false [-Wtautological-constant-out-of-range-compare]
        if (vtype == -1) {
            ~~~~~ ^  ~~
    src/protocol/fastbinary.c:836:16: warning: comparison of constant -1 with expression of type 'TType' (aka 'enum TType') is always false [-Wtautological-constant-out-of-range-compare]
          if (type == -1) {
              ~~~~ ^  ~~
    src/protocol/fastbinary.c:888:14: warning: comparison of constant -1 with expression of type 'TType' (aka 'enum TType') is always false [-Wtautological-constant-out-of-range-compare]
        if (type == -1) {
            ~~~~ ^  ~~
    12 warnings generated.
    cc -bundle -undefined dynamic_lookup -arch x86_64 -arch i386 -Wl,-F. build/temp.macosx-10.10-intel-2.7/src/protocol/fastbinary.o -o build/lib.macosx-10.10-intel-2.7/thrift/protocol/fastbinary.so
    /usr/bin/python -O /tmp/tmpnlFZzW.py
    removing /tmp/tmpnlFZzW.py
  Running setup.py install for scapy
    changing mode of build/scripts-2.7/scapy from 644 to 755
    changing mode of build/scripts-2.7/UTscapy from 644 to 755
    changing mode of /usr/local/bin/scapy to 755
    changing mode of /usr/local/bin/UTscapy to 755

  Running setup.py install for ansicolors
  Running setup.py install for thrift-tools
    changing mode of build/scripts-2.7/thrift-tool from 644 to 755
    changing mode of build/scripts-2.7/thrift-file-reader from 644 to 755
    changing mode of /usr/local/bin/thrift-file-reader to 755
    changing mode of /usr/local/bin/thrift-tool to 755
Successfully installed ansicolors-1.0.2 dpkt-1.9.1 scapy-2.3.1 thrift-0.9.2 thrift-tools-0.0.3

Support thrift 0.10.0

We have several services written in 0.10.0 and would love to be able to use thrift-tools. Is this still being actively supported?

pip install failed

pip install failed, it will throw following error:

Collecting scapy==2.3.1 (from thrift-tools)
  Downloading http://mirrors.aliyun.com/pypi/packages/ee/cd/d20c1e121b09697bf4d7b1b9edde6573fc7d54eefc56860f457a7edfc0de/scapy-2.3.1.zip (1.1MB)
    100% |████████████████████████████████| 1.1MB 296kB/s
    Complete output from command python setup.py egg_info:
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/tmp/pip-install-aaaly1sw/scapy/setup.py", line 35
        os.chmod(fname,0755)

The problem is caused by scapy library which has a bug in setup.py at version 2.3.1 when using python 3.7+ version. thrift-tools package should change scapy version to a higher version.

Thrift IDL parsing and printing

I've added support for .thrift IDL file parsing and printing. Right now the code is just POC and isn't optimized for performance.

Do you think this feature might be useful in upstream repo?

bancek@844b5ef

Example output:

$ FROM_SOURCE=1 bin/thrift-tool --pcap-file thrift_tools/tests/resources/calc-service-binary.pcap dump --show-all --pretty --idl-file thrift_tools/tests/resources/tutorial.thrift 
[00:55:50:387214] 127.0.0.1:51112 -> 127.0.0.1:9090: method=ping, type=call, seqid=0
header: None
fields: []
------>[00:55:50:387370] 127.0.0.1:9090 -> 127.0.0.1:51112: method=ping, type=reply, seqid=0
        header: None
        fields: fields=[]
[00:55:50:387492] 127.0.0.1:51112 -> 127.0.0.1:9090: method=add, type=call, seqid=0
header: None
fields: [('num1', 1), ('num2', 1)]
------>[00:55:50:387596] 127.0.0.1:9090 -> 127.0.0.1:51112: method=add, type=reply, seqid=0
        header: None
        fields: 2
[00:55:50:387696] 127.0.0.1:51112 -> 127.0.0.1:9090: method=calculate, type=call, seqid=0
header: None
fields: [   ('logid', 1),
    (   'w',
        (   'Work',
            [('num1', 1), ('num2', 0), ('op', 'DIVIDE'), ('comment', None)]))]
------>[00:55:50:387840] 127.0.0.1:9090 -> 127.0.0.1:51112: method=calculate, type=reply, seqid=0
        header: None
        fields: ('InvalidOperation', [('whatOp', 4), ('why', 'Cannot divide by 0')])
[00:55:50:388615] 127.0.0.1:51112 -> 127.0.0.1:9090: method=calculate, type=call, seqid=0
header: None
fields: [   ('logid', 1),
    (   'w',
        (   'Work',
            [   ('num1', 15),
                ('num2', 10),
                ('op', 'SUBTRACT'),
                ('comment', None)]))]
------>[00:55:50:388725] 127.0.0.1:9090 -> 127.0.0.1:51112: method=calculate, type=reply, seqid=0
        header: None
        fields: 5
[00:55:50:388811] 127.0.0.1:51112 -> 127.0.0.1:9090: method=getStruct, type=call, seqid=0
header: None
fields: [('key', 1)]
------>[00:55:50:388905] 127.0.0.1:9090 -> 127.0.0.1:51112: method=getStruct, type=reply, seqid=0
        header: None
        fields: ('SharedStruct', [('key', 1), ('value', '5')])

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.