Coder Social home page Coder Social logo

opentracing-contrib / nginx-opentracing Goto Github PK

View Code? Open in Web Editor NEW
495.0 23.0 120.0 4.17 MB

NGINX plugin for OpenTracing

License: Apache License 2.0

JavaScript 8.66% Go 6.79% Shell 3.14% HTML 0.62% Makefile 0.74% C++ 60.15% Python 8.01% PHP 0.78% Dockerfile 10.71% Pug 0.41%
nginx opentracing nginx-module zipkin lightstep jaegertracing tracing

nginx-opentracing's Introduction

nginx-opentracing

Enable requests served by nginx for distributed tracing via The OpenTracing Project.

Dependencies

Installation

For linux-x86_64, pre-compiled binaries are provided for the supported versions of NGINX. These can be dropped into existing NGINX installations provided that NGINX was compiled with the --with-compat option. See example/trivial/ubuntu-x86_64 for an example of how to set it up.

Otherwise, nginx-opentracing can be used from the Docker image or built from source.

Getting Started

First, write a configuration for the tracer used. Below's an example of what a Jaeger configuration might look like:

/etc/jaeger-nginx-config.json

{
  "service_name": "nginx",
  "sampler": {
    "type": "const",
    "param": 1
  },
  "reporter": {
    "localAgentHostPort": "jaeger:6831"
  },
  "headers": {
    "jaegerDebugHeader": "jaeger-debug-id",
    "jaegerBaggageHeader": "jaeger-baggage",
    "traceBaggageHeaderPrefix": "uberctx-"
  },
  "baggage_restrictions": {
    "denyBaggageOnInitializationFailure": false,
    "hostPort": ""
  }
}

See the vendor documentation for details on what options are available.

You can then set up NGINX for distributed tracing by adding the following to nginx.conf:

# Load the OpenTracing dynamic module.
load_module modules/ngx_http_opentracing_module.so;

http {
  # Load a vendor tracer
  opentracing_load_tracer /usr/local/lib/libjaegertracing_plugin.so /etc/jaeger-nginx-config.json;

  # or
  #   opentracing_load_tracer /usr/local/lib/liblightstep_tracer_plugin.so /path/to/config;
  # or
  #   opentracing_load_tracer /usr/local/lib/libzipkin_opentracing_plugin.so /path/to/config;
  # or
  #   opentracing_load_tracer /usr/local/lib/libdd_opentracing_plugin.so /path/to/config;

  # Enable tracing for all requests.
  opentracing on;

  # Optionally, set additional tags.
  opentracing_tag http_user_agent $http_user_agent;

  upstream backend {
    server app-service:9001;
  }

  location ~ {
    # The operation name used for spans defaults to the name of the location
    # block, but you can use this directive to customize it.
    opentracing_operation_name $uri;

    # Propagate the active span context upstream, so that the trace can be
    # continued by the backend.
    # See http://opentracing.io/documentation/pages/api/cross-process-tracing.html
    opentracing_propagate_context;

    proxy_pass http://backend;
  }
}

See Tutorial for a more complete example, Reference for a list of available OpenTracing-related directives.

Docker

A docker image opentracing/nginx-opentracing is provided to support using nginx with OpenTracing in a manner analogous to the nginx Docker image. See here for examples of how to use it.

Additionally, custom images can be built by running

docker build \
       -t opentracing-contrib/nginx-opentracing:latest \
       .

and arguments to tweak the versions used can be provided with

docker build \
       -t opentracing-contrib/nginx-opentracing:latest \
       --build-arg OPENTRACING_CPP_VERSION=master \
       .

Other build arguments

  • OPENTRACING_CPP_VERSION
  • JAEGER_CPP_VERSION
  • GRPC_VERSION

Building From Source

$ tar zxvf nginx-1.9.x.tar.gz
$ cd nginx-1.9.x
$ ./configure --add-dynamic-module=/absolute/path/to/nginx-opentracing/opentracing
$ make && sudo make install

You will also need to install a C++ tracer for either Jaeger, LightStep (Available for OpenTracing 1.5.x), Datadog, or Zipkin. For linux x86-64, portable binary plugins are available:

# Jaeger
wget https://github.com/jaegertracing/jaeger-client-cpp/releases/download/v0.4.2/libjaegertracing_plugin.linux_amd64.so -O /usr/local/lib/libjaegertracing_plugin.so

# LightStep
wget -O - https://github.com/lightstep/lightstep-tracer-cpp/releases/download/v0.8.1/linux-amd64-liblightstep_tracer_plugin.so.gz | gunzip -c > /usr/local/lib/liblightstep_tracer_plugin.so

# Zipkin
wget -O - https://github.com/rnburn/zipkin-cpp-opentracing/releases/download/v0.5.2/linux-amd64-libzipkin_opentracing_plugin.so.gz | gunzip -c > /usr/local/lib/libzipkin_opentracing_plugin.so

# Datadog
wget -O - https://github.com/DataDog/dd-opentracing-cpp/releases/download/v0.3.0/linux-amd64-libdd_opentracing_plugin.so.gz | gunzip -c > /usr/local/lib/libdd_opentracing_plugin.so

Make sure the nginx module for opentracing and a tracer plugin were built against the same version of C++ OpenTracing Library. By default Opentracing v1.6.0 is used.

Testing

Run tests on local machine requires pyenv and tested against version 3.8.5.

$ make test

nginx-opentracing's People

Contributors

alekhrycaiko avatar aramack avatar carlosjgp avatar cezarantohe avatar cgilmour avatar chw-webops avatar cmur2 avatar dependabot[bot] avatar dgoffredo avatar ebachle avatar edernucci avatar eric-price avatar esetnik avatar isaachier avatar jarenglover avatar johejo avatar justinwalz avatar kaimallea avatar lapostoj avatar lucacome avatar lw346 avatar matthiasscholztw avatar miry avatar petermcneely avatar pingles avatar pre-commit-ci[bot] avatar rnburn avatar sejeff avatar verdie-g avatar willgittoes-dd 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  avatar  avatar  avatar  avatar  avatar

nginx-opentracing's Issues

Issue compiling with Nginx 1.17.2

Hello
I tried to directly use ngx_http_opentracing_module.so after pulling it from the site, not founding the exact version (I have Nginx 1.17.2, I saw 1.16.1 and 1.17.3 in open-tracing release compatibility) => I got (obviously afterwards):

[emerg] 6906#6906: module "/etc/nginx/modules/ngx_http_opentracing_module.so" version 1017003 instead of 1017002 in /etc/nginx/nginx.conf:9

Unfortunately I can't see some easy way to upgrade Nginx part (1.17.3 doesn't seem to be available from apt-get), so I tried to follow the hard path to recompile the module :
./configure --with-compat --add-dynamic-module=/etc/nginx/modules/nginx-opentracing-0.9.0/opentracing
(I also tried from 0.8.0 in case)
Then make (doesn't work) so make modules
but I'm getting :

In file included from /etc/nginx/modules/nginx-opentracing-0.8.0/opentracing/src/ngx_http_opentracing_module.cpp:1:0: /etc/nginx/modules/nginx-opentracing-0.8.0/opentracing/src/load_tracer.h:3:38: fatal error: opentracing/dynamic_load.h: No such file or directory

Thank you for your help.

segfault at a ip, sp, error 4 in linux-amd64-libzipkin_opentracing_plugin.so

Hi Team,
Below is my envt details

  1. RHEL 7.6
  2. Nginx-1.15.0
  3. cmake - 3.14.5
  4. Opentracing-cpp - 1.5.0
  5. Nginx-opentracing module - v0.8.0
  6. Zipkin-server - 2.12.9
  7. zipkin plugin - 0.5.2
  8. gcc - 4.8.5

Below is my configuration command used to create Make file

./configure \
        --with-debug \
	--crossbuild=Linux:x86_64 \
	--prefix=/data/nginx \
        --sbin-path=/data/nginx/sbin \
        --conf-path=/data/nginx/nginx.conf \
        --pid-path=/data/nginx/nginx.pid \
        --with-ld-opt="-Wl,-rpath,/usr/local/lib " \
        --lock-path=/data/nginx/lock/subsys/nginx \
        --error-log-path=/data/nginx/logs/error.log \
        --http-log-path=/data/nginx/logs/access.log \
	--with-http_gzip_static_module \
        --with-http_stub_status_module \
        --with-http_ssl_module \
        --with-debug \
        --with-pcre \
	--add-dynamic-module=/absolute/path/to/nginx/nginx-opentracing/opentracing

Below is my Zipkin json file :

{
  "service_name": "nginx",
  "collector_host": "127.0.0.1",
  "collector_port": 9411
}

Below is my nginx.conf file :

{
load_module modules/ngx_http_opentracing_module.so;
worker_processes  1;	
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
	ssl_session_cache    shared:SSL:10m;
	proxy_cache_path /data/nginx/cache keys_zone=one:10m;
	opentracing on;

    # open tracing vendor tracer plugin configure
    opentracing_load_tracer  /usr/local/lib/linux-amd64-libzipkin_opentracing_plugin.so   /data/nginx/zipkin/zipkin-nginx-config.json;
	
    # Set additional tags that capture the value of NGINX variables
    opentracing_tag bytes_sent $bytes_sent;
    opentracing_tag http_user_agent $http_user_agent;
    opentracing_tag request_time $request_time;
    opentracing_tag upstream_addr $upstream_addr;
    opentracing_tag upstream_bytes_received $upstream_bytes_received;
    opentracing_tag upstream_cache_status $upstream_cache_status;
    opentracing_tag upstream_connect_time $upstream_connect_time;
    opentracing_tag upstream_header_time $upstream_header_time;
    opentracing_tag upstream_response_time $upstream_response_time;
	
	# For debugging
    log_format opentracing '[traceId=$http_x_b3_traceid ' ' spanId=$http_x_b3_spanid ] '
    '$remote_addr - $remote_user [$time_local] "$request" '
    '$status $body_bytes_sent "$http_referer" '
    '"$http_user_agent" "$http_x_forwarded_for" '
    '"$host" sn="$server_name" '
    'rt=$request_time '
    'ua="$upstream_addr" us="$upstream_status" '
    'ut="$upstream_response_time" ul="$upstream_response_length" '
    'cs=$upstream_cache_status';

    access_log logs/opentracing.log opentracing;
	sendfile        on;
	keepalive_timeout  65;
	server {
        listen       9001;
        server_name  localhost;
		proxy_cache one;
        proxy_cache_valid any 1m;
		location / {
           #proxy_pass http://backend/;
           opentracing_propagate_context;
		}
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

While validation the configuration i'm not seeing any issue

$ nginx -t 
nginx: the configuration file /data/nginx/nginx.conf syntax is ok
nginx: configuration file /data/nginx/nginx.conf test is successful

While starting nginx and while doing curl (curl localhost:9001) i'm seeing below error in error.log
$ nginx

$ tail -f logs/error.log
2019/07/16 12:29:52 [notice] 23368#0: signal process started
2019/07/16 12:29:52 [alert] 11724#0: worker process 23375 exited on signal 11
2019/07/16 12:29:52 [alert] 11724#0: worker process 23387 exited on signal 11

when run following command (to understand what the Linux kernel thinks about some trouble.)

$ dmesg | grep -i error

[106329.324819] nginx[23375]: segfault at a ip 00007f89e86a88ab sp 00007ffc8baffe70 error 4 in linux-amd64-libzipkin_opentracing_plugin.so[7f89e868b000+17a000]
[106329.425811] nginx[23387]: segfault at a ip 00007f89e86a88ab sp 00007ffc8baffec0 error 4 in linux-amd64-libzipkin_opentracing_plugin.so[7f89e868b000+17a000]

Any help is appreciated.

The Docker file doesn't build

How to replicate

git clone https://github.com/opentracing-contrib/nginx-opentracing.git
cd nginx-opentracing/docker
docker build -t nginx:opentracing .

the error displayed is

Scanning dependencies of target jaegertracing
[  0%] Building CXX object CMakeFiles/jaegertracing.dir/src/jaegertracing/Config.cpp.o
In file included from /tmp/tmp.FPf1d0pTos/jaeger-cpp-client/src/jaegertracing/Config.h:21:0,
                 from /tmp/tmp.FPf1d0pTos/jaeger-cpp-client/src/jaegertracing/Config.cpp:17:
/tmp/tmp.FPf1d0pTos/jaeger-cpp-client/src/jaegertracing/baggage/RestrictionsConfig.h:24:27: fatal error: yaml-cpp/yaml.h: No such file or directory
 #include <yaml-cpp/yaml.h>
                           ^
compilation terminated.
CMakeFiles/jaegertracing.dir/build.make:62: recipe for target 'CMakeFiles/jaegertracing.dir/src/jaegertracing/Config.cpp.o' failed
make[2]: *** [CMakeFiles/jaegertracing.dir/src/jaegertracing/Config.cpp.o] Error 1
make[1]: *** [CMakeFiles/jaegertracing.dir/all] Error 2
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/jaegertracing.dir/all' failed
Makefile:127: recipe for target 'all' failed
make: *** [all] Error 2

Invalid duration time in Jaeger

Hi,

I am trying to integrate nginx with jaeger, but in jaeger UI am getting long duration time for a nginx request.
When i hit / on my nginx server it takes less than a second to load, but in jaeger its showing 18+ seconds.

nginx-load-time

request-wrong-duration

spans

I have made a small fix in opentracing_request_instrumentor.cpp and after that its working as expected.
what i changed:
replaced the
"auto timepoint = ngx_timeofday()
auto finish_timestamp =opentracing::convert_time_pointstd::chrono::steady_clock(to_system_timestamp(timepoint->sec, timepoint->msec)); " to

auto finish_timestamp = std::chrono::steady_clock::now();

My env details:

  1. Jaeger: all jaeger components running in single container
    docker run -d -e COLLECTOR_ZIPKIN_HTTP_PORT=9411 -p5775:5775/udp -p6831:6831/udp -p6832:6832/udp -p5778:5778 -p16686:16686 -p14268:14268 -p9411:9411 jaegertracing/all-in-one:latest

  2. Nginx - Used the docker image which described in this project
    rnburn/nginx-opentracing:latest

  3. My nginx conf file

user nginx;
worker_processes 1;

error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

load_module modules/ngx_http_opentracing_module.so;
load_module modules/ngx_http_jaeger_module.so;

events {
worker_connections 1024;
}

http {

jaeger_service_name nginx-opentracing-test-service;

opentracing on;

jaeger_sampler_type const;

jaeger_sampler_param 1;

jaeger_reporter_log_spans on;

jaeger_sampling_server_url http://10.112.81.82:5778;


jaeger_reporter_local_agent_host_port 10.112.81.82:6831;

include       /etc/nginx/mime.types;
default_type  application/octet-stream;

log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                  '$status $body_bytes_sent "$http_referer" '
                  '"$http_user_agent" "$http_x_forwarded_for"';

access_log  /var/log/nginx/access.log  main;

sendfile        on;
#tcp_nopush     on;

keepalive_timeout  65;

#gzip  on;

include /etc/nginx/conf.d/*.conf;

}

Unexpected error using gcc-8

In file included from src/core/ngx_core.h:51,
                 from /tmp/build/nginx-opentracing-0.5.0/opentracing/src/opentracing_directive.h:6,
                 from /tmp/build/nginx-opentracing-0.5.0/opentracing/src/opentracing_directive.cpp:1:
/tmp/build/nginx-opentracing-0.5.0/opentracing/src/opentracing_directive.cpp: In function 'char* ngx_opentracing::add_opentracing_tag(ngx_conf_t*, ngx_array_t*, ngx_str_t, ngx_str_t)':
src/core/ngx_string.h:88:58: error: 'void* memset(void*, int, size_t)' clearing an object of non-trivial type 'struct ngx_opentracing::opentracing_tag_t'; use assignment or value-initialization instead [-Werror=class-memaccess]
 #define ngx_memzero(buf, n)       (void) memset(buf, 0, n)
                                                          ^
/tmp/build/nginx-opentracing-0.5.0/opentracing/src/opentracing_directive.cpp:92:3: note: in expansion of macro 'ngx_memzero'
   ngx_memzero(tag, sizeof(opentracing_tag_t));
   ^~~~~~~~~~~
In file included from /tmp/build/nginx-opentracing-0.5.0/opentracing/src/opentracing_directive.cpp:5:
/tmp/build/nginx-opentracing-0.5.0/opentracing/src/opentracing_conf.h:13:8: note: 'struct ngx_opentracing::opentracing_tag_t' declared here
 struct opentracing_tag_t {
        ^~~~~~~~~~~~~~~~~
cc1plus: all warnings being treated as errors
make[1]: *** [objs/Makefile:2716: objs/addon/src/opentracing_directive.o] Error 1

Mirror requests are not propagated correctly

I have a nginx config with a proxy_pass to an upstream server, along with a mirror directive to another upstream server in the same location. I'm trying to configure tracing to zipkin for both the proxied and mirrored request, but it seems if I enable the opentracing_propagate_context on the /mirror location, the resulting trace is wrong, with zipkin displaying the mirrored request and the proxied one as part of the same span.

I tried different directives from the reference guide, such as changing the location name, but to no avail.

Here's a sample of my config:

...
location /events {
          opentracing on;
          opentracing_propagate_context;

          proxy_set_header Host $http_host;
          proxy_pass http://$trk_rest_backend;

          mirror /mirror;
          mirror_request_body on;
        }

        location = /mirror {
          internal;
          proxy_pass_request_body on;
          proxy_set_header Host $http_host;
          proxy_set_header X-Original-URI $request_uri;

          opentracing on;
          opentracing_propagate_context;

          proxy_pass http://trk_raw_request_store$request_uri;
        }
...

And this is what I see in Zipkin:
screenshot 2019-01-14 at 10 10 18
As you can see, there's no /mirror location traced, and the trk-raw-request-store trace, which should be child of the mirror, it's instead listed as child of the proxied upstream trace.

Any ideas or suggestions as to why this might be happening?

Thanks.

Set opentracing context for a request in an earlier phase

I'm working on kubernetes/ingress-nginx#3783 to enable tracing of each Nginx phase we run Lua code. I've noticed that ngx.var.opentracing_binary_context is not set at rewrite phase and when I try to access it in Lua I get:

2019/02/20 14:40:54 [error] 42#42: *374 failed to expand opentracing_context_ for request 0000564FD8E6D060: no OpenTracingContext attached to request, client: 172.17.0.1, server: example.com, request: "GET /echo HTTP/1.1", host: "example.com"

Looking at the source code, I noticed that opentracing runs after rewrite phase:

&core_main_config->phases[NGX_HTTP_PREACCESS_PHASE].handlers));

Can we inject it at NGX_HTTP_POST_READ_PHASE or NGX_HTTP_SERVER_REWRITE_PHASE? According to http://nginx.org/en/docs/dev/development_guide.html#http_phases NGX_HTTP_POST_READ_PHASE is the earliest phase.

Question: Remotely controlled sampler for Jaeger?

I noticed that jaeger-client-cpp supported remotely controlled sampler (in which, it will consult the sampler for sample type and rate). I am using nginx ingress and asked them about this feature, noticing that their opentracing.json template does not include the parameter to define the URL kubernetes/ingress-nginx#3894 (comment)

But it seems nginx opentracing is not enabling this feature, is it correct?

Request: precompiled release for nginx 1.14.2

Debian 10.0 relies on 1.14.2 and not 1.14.0. We don't want to also own the build process for this plugin and would greatly appreciate adding 1.14.2 to the precompiled releases if this is possible!

Issue opened on behalf of Cognite/LightStep, CC @rnburn

Dynamic opentracing operation name for each request

i am not able to set the opentracing_operation_name dynamically for each request. Lets say if i have a variable which is initialised to nil in conf file and later i am setting the value based on some if condition, now i want to set the opentracing_operation_name by using the value of the variable.

Scenario:

set $test_variable nil;
blah...
blah...
proxy...
if (some-condition1)
set $test_variable opearionname1
if (some-condition2)
set $test_variable opearionname2

opentracing_operation_name $test_variable

Problem:
Here the problem is the operation name is set on entry phase of the request (opentracing_request_instrumentor.cpp, line 92) , by that time the variable is not initialised so opentracing_operation_name set to nil.

Solution:

I just made change in on_log_request method (opentracing_request_instrumentor.cpp) to set the value of opentracing_operation_name in request exit phase, after that am able to achieve the dynamic opentracing operation name (ie., am able to set the value of opentracing_operation_name dynamically for each request)

Code change
Added blow three lines in on_log_request method in opentracing_request_instrumentor.cpp file,

auto core_loc_conf = static_cast<ngx_http_core_loc_conf_t *>(
ngx_http_get_module_loc_conf(request_, ngx_http_core_module));

auto loc_conf = static_cast<opentracing_loc_conf_t *>(
ngx_http_get_module_loc_conf(request_, ngx_http_opentracing_module));

request_span_->SetOperationName(get_request_operation_name(request_, core_loc_conf, loc_conf));

Missing modules/ngx_http_opentracing_module.so

Currently, I am trying to find where is the module or source code to build the module ngx_http_opentracing_module.so.

There is not any information within the repository and tutorial how to obtain that module

Error reporting using openresty

Using openresty alone to start the error reporting, the error information is as follows:
1
If using the Official Directory example and starting with Docker can work properly, Then I use the official website example to start without docker, report the same error, and start the openresty command:
/ usr/local/openresty/nginx/sbin/nginx-p pwd-c conf/nginx.conf

Why is this?

Core dump in Centos

Hello,

I'm building ngx-opentracing for Openresty and each time that a request is in place I got the following core dump:

Program terminated with signal 11, Segmentation fault.
#0  0x00007fc5343de0e3 in std::_Function_handler<opentracing::v2::expected<void, std::error_code> (opentracing::v2::string_view, opentracing::v2::string_view), jaegertracing::propagation::Propagator<opentracing::v2::HTTPHeadersReader const&, opentracing::v2::HTTPHeadersWriter const&>::extract(opentracing::v2::HTTPHeadersReader const&) const::{lambda(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)#1}>::_M_invoke(std::_Any_data const&, opentracing::v2::string_view&&, std::_Any_data const&) () from /usr/local/lib/libjaegertracing_plugin.so
Missing separate debuginfos, use: debuginfo-install openresty-1.15.8.2-6.el7.x86_64
(gdb) bt
#0  0x00007fc5343de0e3 in std::_Function_handler<opentracing::v2::expected<void, std::error_code> (opentracing::v2::string_view, opentracing::v2::string_view), jaegertracing::propagation::Propagator<opentracing::v2::HTTPHeadersReader const&, opentracing::v2::HTTPHeadersWriter const&>::extract(opentracing::v2::HTTPHeadersReader const&) const::{lambda(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)#1}>::_M_invoke(std::_Any_data const&, opentracing::v2::string_view&&, std::_Any_data const&) () from /usr/local/lib/libjaegertracing_plugin.so
#1  0x00007fc534d1ac36 in ?? () from /usr/local/openresty/nginx/modules/ngx_http_opentracing_module.so
#2  0x00007fc5343dbffe in jaegertracing::propagation::Propagator<opentracing::v2::HTTPHeadersReader const&, opentracing::v2::HTTPHeadersWriter const&>::extract(opentracing::v2::HTTPHeadersReader const&) const () from /usr/local/lib/libjaegertracing_plugin.so
#3  0x00007fc5343dc31a in jaegertracing::Tracer::Extract(opentracing::v2::HTTPHeadersReader const&) const ()
   from /usr/local/lib/libjaegertracing_plugin.so
#4  0x00007fc534d1ad2d in ngx_opentracing::extract_span_context(opentracing::v2::Tracer const&, ngx_http_request_s const*) ()
   from /usr/local/openresty/nginx/modules/ngx_http_opentracing_module.so
#5  0x00007fc534d208c4 in ngx_opentracing::RequestTracing::RequestTracing(ngx_http_request_s*, ngx_http_core_loc_conf_s*, ngx_opentracing::opentracing_loc_conf_t*, opentracing::v2::SpanContext const*) () from /usr/local/openresty/nginx/modules/ngx_http_opentracing_module.so
#6  0x00007fc534d1e961 in void std::vector<ngx_opentracing::RequestTracing, std::allocator<ngx_opentracing::RequestTracing> >::_M_emplace_back_aux<ngx_http_request_s*&, ngx_http_core_loc_conf_s*&, ngx_opentracing::opentracing_loc_conf_t*&>(ngx_http_request_s*&, ngx_http_core_loc_conf_s*&, ngx_opentracing::opentracing_loc_conf_t*&) () from /usr/local/openresty/nginx/modules/ngx_http_opentracing_module.so
#7  0x00007fc534d1e4e3 in ngx_opentracing::OpenTracingContext::OpenTracingContext(ngx_http_request_s*, ngx_http_core_loc_conf_s*, ngx_opentracing::opentracing_loc_conf_t*) () from /usr/local/openresty/nginx/modules/ngx_http_opentracing_module.so
#8  0x00007fc534d1d87e in ngx_opentracing::on_enter_block(ngx_http_request_s*) ()
   from /usr/local/openresty/nginx/modules/ngx_http_opentracing_module.so
#9  0x0000000000459bbc in ngx_http_core_rewrite_phase ()
#10 0x00000000004555f5 in ngx_http_core_run_phases ()
#11 0x00000000004605b1 in ?? ()
#12 0x0000000000460904 in ?? ()
#13 0x000000000044a027 in ?? ()
#14 0x0000000000440f9b in ngx_process_events_and_timers ()
#15 0x0000000000449780 in ngx_single_process_cycle ()
#16 0x000000000042181a in main ()
(gdb)

The way that I installed is the following spec + with the following change:

Spec:
https://github.com/openresty/openresty-packaging/blob/master/rpm/SPECS/openresty.spec

Config:

build
./configure \
    --prefix="%{orprefix}" \
    --with-cc-opt="-DNGX_LUA_ABORT_AT_PANIC -I%{zlib_prefix}/include -I%{pcre_prefix}/include -I%{openssl_prefix}/include" \
    --with-ld-opt="-L%{zlib_prefix}/lib -L%{pcre_prefix}/lib -L%{openssl_prefix}/lib -Wl,-rpath,%{zlib_prefix}/lib:%{pcre_prefix}/lib:%{openssl_prefix}/lib" \
    --with-pcre-jit \
    --without-http_rds_json_module \
    --without-http_rds_csv_module \
    --without-lua_rds_parser \
    --with-stream \
    --with-stream_ssl_module \
    --with-stream_ssl_preread_module \
    --with-http_v2_module \
    --without-mail_pop3_module \
    --without-mail_imap_module \
    --without-mail_smtp_module \
    --with-http_stub_status_module \
    --with-http_realip_module \
    --with-http_addition_module \
    --with-http_auth_request_module \
    --with-http_secure_link_module \
    --with-http_random_index_module \
    --with-http_gzip_static_module \
    --with-http_sub_module \
    --with-http_dav_module \
    --with-http_flv_module \
    --with-http_mp4_module \
    --with-http_gunzip_module \
    --with-threads \
    --with-luajit-xcflags='-DLUAJIT_NUMMODE=2 -DLUAJIT_ENABLE_LUA52COMPAT' \
    --with-dtrace-probes \
    --add-dynamic-module="/tmp/nginx-opentracing-0.9.0/opentracing" \
    %{?_smp_mflags}

It happens to me with 0.3.0 version, and I tried with the latest stable and always happens, any idea where this fails come from?

I tried the example in Openresty-dockerfile and worked perfectly. Any hint here?

Regards

zipking sampling percentage configuration

Currently there is no way (please correct me if I wrong) to specify sampling percentage for Zipkin tracer. This renders zipkin support not so usable on high load prod environments, as amount of traces generated is more than actual traffic.

Would it be possible to provide sampling param same as for eg. jaeger?

localAgentHostPort from env variable

Cannot find any examples nor issues with this question, could an environment variable be used to set agent host?

Context: a jaeger agent is placed on every node in kubernetes deployment and to eliminate extra time consumption packets should be send straight to node IP. Node IP could be set dynamically into env var:

        env:
        - name: JAEGER_AGENT_HOST
          valueFrom:
            fieldRef:
              fieldPath: status.hostIP

openresty with nginx 1.13.6 and opentracing

Hello! Are you planning to release the pre-compiled binary (.so) for the openresty with nginx 1.13.6 anytime? I tried to compile in my setup, but getting into one issue after the other.

I see there is related issue - #87. It would be very helpful if you can release the compiled binary.

Question: Can I configure a sampling rate?

Hi,

Thank you for this module, looks really great.
However, I'm a little bit scary to enable this on production nginx. I was not able to find any control on amount tracing spans to create. Do I understand correctly that it will create a span for every request?

For high production traffic, it would be great to have an option to trace only, let's say, 0.5% or 1% of the requests.

Does this support propagating context from an incoming request?

Hi,

I was trying to set up and run through the example that @aledbf ported from OpenZipkin, which starts traces in the browser and propagates them through two backend services. So far, I haven't been able to get full trace propagation through Nginx.

With tracing support turned on in Nginx, the traces I see in Zipkin start with Nginx spans, and when I turn off tracing in Nginx, the traces start with the browser's spans. In both cases, the spans from the example 'frontend' and 'backend' services are correctly stitched to the traces. I infer from this that the nginx-opentracing module is not correctly extracting the trace context from the browser's requests and using that context to create child spans.

I'm confused, however, because I see what I believe is the logic for extracting context from an incoming request. Perhaps the issue is specifically related to CORS? I don't understand how that would be so, though, because the setup I described works when turning off the tracing module in nginx (specifically, I have configured Nginx to allow the trace context headers in CORS requests: x-b3-sampled, x-b3-spanid, and x-b3-traceid).

Is there something specific that needs to be configured in order for this module to propagate Zipkin context headers from incoming to outgoing (downstream to upstream) requests? And if you think this should work, do you have any suggestions about what I might do to troubleshoot?

Thank you!

[EDIT: renamed from "Does this support propagating context from an incoming request?" to "Does this support extracting trace context from an incoming request?"]

Host header is being overwritten with upstream name

If nginx is configured on host my.host, with a backend set up, my-backend, when I make a request to my.host/some-path with a header Host: my.host, then the Host header is being overwritten with my-backend when propagated to the upstream.

Here's an example failing test:

diff --git a/test/environment/app.py b/test/environment/app.py
index c190af6..d51546a 100644
--- a/test/environment/app.py
+++ b/test/environment/app.py
@@ -12,5 +12,11 @@ def has_span_context_redirect():
     assert 'x-ot-span-context' in request.headers
     return '', status.HTTP_301_MOVED_PERMANENTLY
 
[email protected]('/has-host-header')
+def has_host_header():
+    assert 'host' in request.headers
+    assert 'localhost' == request.headers['host']
+    return 'OK'
+
 if __name__ == '__main__':
     app.run(debug=True,host='0.0.0.0')
diff --git a/test/environment/nginx.conf b/test/environment/nginx.conf
index 0ee3ab8..67b72ff 100644
--- a/test/environment/nginx.conf
+++ b/test/environment/nginx.conf
@@ -20,6 +20,10 @@ http {
       proxy_pass http://backend/has-span-context;
     }
 
+    location = /has-host-header {
+      opentracing_propagate_context;
+      proxy_pass http://backend/has-host-header;
+    }
+
     location = /manual-propagation {
       proxy_set_header x-ot-span-context $opentracing_context_x_ot_span_context;
 
diff --git a/test/nginx_opentracing_test.py b/test/nginx_opentracing_test.py
index c7cb8c0..2929983 100644
--- a/test/nginx_opentracing_test.py
+++ b/test/nginx_opentracing_test.py
@@ -87,6 +87,15 @@ class NginxOpenTracingTest(unittest.TestCase):
         with open(os.path.join(self.workdir, "traces", "nginx.json")) as f:
             self.nginx_traces = json.load(f)
 
+    def testHostHeader(self):
+        self.conn.request("GET", "/has-host-header")
+        response = self.conn.getresponse()
+
+        self.assertEqual(response.status, 200)
+        self._stopEnvironment()
+
+        self.assertEqual(len(self.nginx_traces), 2)
+
     def testTrivialRequest(self):
         self.conn.request("GET", "/")
         response = self.conn.getresponse()

Having tested this behaviour in real nginx, it may also be stripping out proxy_set_header directives if defined in the http block.

openresty and nginx-opentracing

Do you envision adding a pre-compiled binary for openresty in the Github releases?

Today the openresty bundles with nginx 1.13.6. However, the binary you provide is 1.13.12.

I can tell from this you have openresty support. However, I got lost in the moving parts.

It looks like in order to build for openresty the dependencies are opentracing-cpp, lua bridger tracer and jaeger correct?

I suspect if given a pre-compiled binary I would still have compiled openresty with the right flags to work with dynaimc modules.

Support `X-B3-TraceId` headers only

Hi guys,
I have issue when I send X-B3-TraceId header only -- it means without other headers like X-B3-SpanId, ...

I see error message:

2019/02/14 08:18:09 [error] 2480#2480: *2690023 failed to extract an opentracing span context from request 00005624140F3D60: opentracing: SpanContext data corrupted in Extract carrier, client: x.x.x.x, server: xxx.com, request: "PUT /some/path HTTP/1.1", host: "xxx.com"

Is there any chance that you can add support for sending X-B3-TraceId only?
You could take this trace id and use it for span id, etc.

My motivation is following:
We could change all our clients to send additional headers as well but we are waiting for official W3C tracing headers spec and we don't want to change it twice.

Thanks

Allow passing tags in for things like hostname or ip

The hostname tag in an ingress controller pod ends up being the name of the container, something like ingress-nginx-controller-xyzz123. I'd like to use the kubernetes downward api to create an env var such as NODE_NAME that contains the actual hostname of the kubelet running. This way, traces from the ingress controller will show the actual hostname of the pod running this code.

It doesn't appear to currently support passing tags to the tracer constructor.

how to resolve the problem "nginx: [emerg] unknown "opentracing_context_uber_trace_id" variable"

I am trying to add the trace chain to nginx, and I have compiled all the related so files(ngx_http_opentracing_module.so、libopentracing.so). When loading the cofigure file according to the example, it prompts "nginx: [emerg] unknown "opentracing_context_uber_trace_id" variable"" error, Can anybody tell me What is the reason, and how to resolve it, thank you!

I am using "nginx-opentracing-0.7.0", "opentracing-cpp-1.5.0" and "jaeger-client-cpp-0.4.2". the content of related configure file is:
nginx.conf

load_module /opt/jaeger/test/ngx_http_opentracing_module.so;

events {}

http {
  opentracing on;

  opentracing_load_tracer /opt/jaeger/test/libjaegertracing_plugin.so /opt/jaeger/test/jaeger-config.json;

  server {
    root /var/www;
    error_log /var/log/nginx/debug.log debug;
    listen 8080;
    server_name localhost;

    location = / {
      #include fastcgi_params;
      #fastcgi_param SCRIPT_FILENAME /var/www/app/app.php;
      #fastcgi_pass php_fpm:9000;
      opentracing_fastcgi_propagate_context;
    }
  }
}

jaeger-config.json

{
  "service_name": "nginx",
  "diabled": false,
  "reporter": {
    "logSpans": true,
    "localAgentHostPort": "127.0.0.1:6831"
  },
  "sampler": {
    "type": "const",
    "param": "1"
  }
}

error:opentracing/dynamic_load.h:no the files or directory

I use building from source,when make && make install ,make a mistake,the following information:

In file included from /usr/local/nginx-opentracing-master/opentracing//src/ngx_http_opentracing_module.cpp:1:0:
/usr/local/nginx-opentracing-master/opentracing//src/load_tracer.h:3:38: 致命错误:opentracing/dynamic_load.h:没有那个文件或目录
#include <opentracing/dynamic_load.h>
^
编译中断。
make[1]: *** [objs/addon/src/ngx_http_opentracing_module.o] 错误 1
make[1]: *** 正在等待未完成的任务....
make[1]: Leaving directory `/usr/local/nginx-1.14.0'
make: *** [build] 错误 2

Question: is ok to get the same x-b3-traceid for different request without a root context?

while true;do kubectl exec -n ingress-nginx   nginx-ingress-controller-76bdfb5c64-2hvcc  -it -- curl localhost/echo -H 'Host: example.com'|grep traceid ;done
	x-b3-traceid=0a1ae1fabcda88f9
	x-b3-traceid=267495655b75771f
	x-b3-traceid=a1eebdbfedb047c5
	x-b3-traceid=0c98081b94f174ff
	x-b3-traceid=0a1ae1fabcda88f9
	x-b3-traceid=c025d275e340ad21
	x-b3-traceid=f11689ab9675606e
	x-b3-traceid=e9d46ae5f3e04de4
	x-b3-traceid=9c1a32235f7413c5
	x-b3-traceid=69d3e6753e1fd345
	x-b3-traceid=69d3e6753e1fd345
	x-b3-traceid=372835f40f77de4d
	x-b3-traceid=22ffc11d5144998c
	x-b3-traceid=c6557c10db6655ac
	x-b3-traceid=5b0e43a659640f57
	x-b3-traceid=267495655b75771f
	x-b3-traceid=372835f40f77de4d
	x-b3-traceid=75c571e2172456d1
	x-b3-traceid=97f89ce39d582611
	x-b3-traceid=13bf9e8b27046f49
	x-b3-traceid=a1eebdbfedb047c5
	x-b3-traceid=be05273935e4ee03
	x-b3-traceid=5b0e43a659640f57
	x-b3-traceid=e39b41505f07beb8
	x-b3-traceid=71593a170e6a243b
	x-b3-traceid=67650848024984b1
	x-b3-traceid=a46d7d742e048b69
	x-b3-traceid=ce79afd8d60822b1
	x-b3-traceid=71593a170e6a243b
	x-b3-traceid=75c571e2172456d1
	x-b3-traceid=ce79afd8d60822b1
	x-b3-traceid=97f89ce39d582611
	x-b3-traceid=b7f0956e451fac0b
	x-b3-traceid=0b1921b459b7c4c3
	x-b3-traceid=f11689ab9675606e
	x-b3-traceid=e9d46ae5f3e04de4
	x-b3-traceid=fe446a8a0acbde99
	x-b3-traceid=d7258f18771c66f6
	x-b3-traceid=be05273935e4ee03
	x-b3-traceid=e39b41505f07beb8
	x-b3-traceid=9c1a32235f7413c5
	x-b3-traceid=84c9234b81b3f238
	x-b3-traceid=5b0e43a659640f57
	x-b3-traceid=b7f0956e451fac0b
	x-b3-traceid=67650848024984b1
	x-b3-traceid=13bf9e8b27046f49
	x-b3-traceid=a46d7d742e048b69
	x-b3-traceid=e39b41505f07beb8
	x-b3-traceid=a3facea2962664f4

Request: precompiled release for Nginx 1.14.2

Thank you for providing precompiled releases for earlier Nginx versions - could I be so bold to request a binary for 1.14.2, given that there have been some (minor) security issues with 1.14.0?

nginx-opentracing compile error

my compilation environment is:
gcc(cc) gcc (GCC) 5.1.0;
cmake version 3.6.2;
nginx1.10.3
,but when i compiled nginx and generated the ngx_http_opentracing_module.so file normally,the following error occurred to execute /usr/local/nginx/sbin/nginx -t:
nginx: [emerg] dlopen() "/usr/local/nginx/modules/ngx_http_opentracing_module.so" failed (/usr/local/nginx/modules/ngx_http_opentracing_module.so: undefined symbol: _ZN11opentracing11v3_unstable29DynamicallyLoadTracingLibraryEPKcRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE) in /usr/local/nginx/conf/nginx.conf:2
image

i run command:
nm ngx_http_opentracing_module.so |grep Dynamic:
0000000000008820 W _ZN11opentracing11v3_unstable20DynamicLibraryHandleD0Ev
0000000000008890 W _ZN11opentracing11v3_unstable20DynamicLibraryHandleD1Ev
0000000000008890 W _ZN11opentracing11v3_unstable20DynamicLibraryHandleD2Ev
U _ZN11opentracing11v3_unstable29DynamicallyLoadTracingLibraryEPKcRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
0000000000009710 T _ZN15ngx_opentracing11load_tracerEP9ngx_log_sPKcS3_RN11opentracing11v3_unstable27DynamicTracingLibraryHandleERSt10shared_ptrINS5_6TracerEE
0000000000008830 W _ZNSt10unique_ptrIKN11opentracing11v3_unstable27DynamicTracingLibraryHandleESt14default_deleteIS3_EED1Ev
0000000000008830 W ZNSt10unique_ptrIKN11opentracing11v3_unstable27DynamicTracingLibraryHandleESt14default_deleteIS3_EED2Ev
000000000000e600 r ZZNR11opentracing11v3_unstable8expectedINS0_27DynamicTracingLibraryHandleESt10error_codeEdeEvE19__PRETTY_FUNCTION

image

runcommand: grep DynamicallyLoadTracingLibrary * -R
image

vim ngx_http_opentracing_module.so can find the function definition:
image

Does anyone know the possible cause?or may it related to the gcc version?

Support tracing with grpc

Currently, opentracing_propagate_context uses proxy_set_header to inject span contexts into upstream requests. It would be nice to get support for injecting into requests to grpc server, now that nginx supports grpc.

Unable to set context header for jaeger

I seem to be having an issue setting a custom header for the propagation of the traceid.

I have a config like the following:

load_module modules/ngx_http_opentracing_module.so;
load_module modules/ngx_http_jaeger_module.so;

events {
  worker_connections  1024;  ## Default: 1024
}

http {
   opentracing on;
   jaeger_trace_context_header_name custom-trace-id;
   jaeger_service_name nginx;
   jaeger_sampler_type const;
   jaeger_sampler_param 1;

   server {
      location /dump {
         proxy_pass http://localhost:8080;
      }
   }
}

However, when I issue a simple curl command against this endpoint, curl localhost/dump, the downstream service that gets proxied to still sees the Uber-Trace-Id header and my custom trace header is nowhere to be found. I'm not sure if I'm doing something wrong, or if I'm not understanding what that configuration parameter is really supposed to do. I'm using the latest docker container at rnburn/nginx-opentracing:latest to run this.

Any help on this would be appreciated.

Release does not work with Alpine docker image

Looks lie all the release is built with Ubuntu and the associated dev packages. This casues a lot of issue loading that in alpine. There are suggestion of installtion lib-compat but it will error out on standard c library symbol on function call.

.
[emerg] dlopen() "/usr/local/openresty/nginx/modules/ngx_http_opentracing_module.so" failed (Error loading shared library ld-linux-x86-64.so.2: No such file or directory (needed by /usr/local/openresty/nginx/modules/ngx_http_opentracing_module.so))

Problem with gcc 4.8.5

Hello, I try to compile nginx-opentracing with gcc 4.8.5 on centos 7 and have this problem:
./nginx-opentracing-0.7.0/opentracing/src/discover_span_context_keys.cpp: In constructor «ngx_opentracing::{anonymous}::HeaderKeyWriter::HeaderKeyWriter(ngx_pool_t*, std::vector<opentracing::v2::string_view>&)»: ./nginx-opentracing-0.7.0/opentracing/src/discover_span_context_keys.cpp:18:32: error: invalid initialization of non-const reference of type «std::vector<opentracing::v2::string_view>&» from an rvalue of type «<brace-enclosed initializer list>» : pool_{pool}, keys_{keys} {}

Building instructions are incomplete

I can't build this dynamic library following the README.md instructions.
I try to replicate the process by using the same commands as the Docker image with no luck.

Can you please list the library versions compatible and tested with this module?

I also try to build only opentracing-cpp and zipkin-cpp libraries and only use those modules...
Everything builds successfully but when I try to use the modules I have this error

2018/01/17 14:00:36 [emerg] 7#7: dlopen() "/etc/nginx/modules/ngx_http_zipkin_module.so" failed (Error loading shared library libcurl.so.4: No such file or directory (needed by /usr/local/lib/libzipkin.so.0)) in /etc/nginx/nginx.conf:5
nginx: [emerg] dlopen() "/etc/nginx/modules/ngx_http_zipkin_module.so" failed (Error loading shared library libcurl.so.4: No such file or directory (needed by /usr/local/lib/libzipkin.so.0))

php-fpm

Hello,

I'm using nginx to proxy to php-fpm. How do I forward a span context to this type of backend? I can set a fastcgi_param that is available in my backend but I'm not sure what the variable names are. Please forgive my ignorance with php, nginx, c++, etc. Not my typical stack.

Anyway, this is what I'm more or less trying to do:

fastcgi_param HTTP_UBER_TRACE_ID $opentracing_context_trace_id;

opentracing_propagate_context; doesn't seem to pass the necessary HTTP headers to php-fpm, and from what I understand the only way to have this type of functionality is to pass via fastcgi_param.

Thanks so much for your time.

Ben

Tag http.status_code is missing when log_subrequest is on

Steps to Reproduce

Given nginx.conf

load_module /etc/nginx/modules/ngx_http_opentracing_module.so;

worker_processes  1;
error_log /dev/stdout debug;

events {
  worker_connections 1024;
}
http {
  opentracing on;
  opentracing_load_tracer /usr/local/lib/libjaegertracing_plugin.so /etc/jaeger-config.json;

  server {
    listen 8080;
    access_log /dev/stdout;

    log_subrequest on;

    location = /auth {
      internal;
      opentracing_propagate_context;
      alias /usr/share/nginx/html/;
      try_files index.html =404;
    }

    location /test {
      opentracing_propagate_context;
      auth_request /auth;
      alias /usr/share/nginx/html/;
      try_files index.html =404;
    }
  }
}

jaeger-config.json

{
  "service_name": "nginx",
  "reporter": {
    "localAgentHostPort": "jaeger:6831"
  },
  "sampler": {
    "type": "const",
    "param": "1"
  }
}
  1. Start a container with docker run -p 8080:8080 -v ~/nginx.conf:/etc/nginx/nginx.conf -v ~/jaeger-config.json:/etc/jaeger-config.json --rm opentracing/nginx-opentracing:0.7.0
  2. Visit http://localhost:8080/test.

Actual Result

Tag http.status_code is missing in all spans, and there is additional /auth location span,

Here is the trace 7a6a2ee92cb5032.json and screenshot, when log_subrequest on.

screen shot 2018-10-06 at 21 40 20

Expected Result

  • Tag http.status_code and error should be correctly set in all spans.
  • /auth location span should be not existed, or it should be child of /test location span, not child of root span. Either way works to me.

Here is the trace eb660a74f1c03256.json and screenshot, when log_subrequest off.

screen shot 2018-10-06 at 21 40 44

How to set the request path as trace name?

I'm using the latest Docker image, proxying traffic to gRPC servers. I have a location like service.v1.Service/, and all traces for routes to that service aren't being named correctly to for example service.v1.Service/GetData.
Is there a way to enable this to be the span name?

how can i transfer current request to proxypass request?

English is not my native language, the following is translated by Google

How should I get the TraceId of the current request and put it in the header of http Pass in the next hop such as reverse proxy(proxy_pass ,upstream{}).
X-B3-TraceId
X-B3-SpanId
X-B3-ParentSpanId
X-B3-Sampled
X-B3-Flags
I tried this setting unsuccessfully, in the back-end php-fpm did not get to this http header

e.g.
when i access
http://test.com/a.html will make a TraceId ==1234

  1. a.html content

``

<script src="http://test.com/b.css"> </script> <script src="http://test.com/c.js"> </script> i am a.html

``

2.then c.js send a ajax request
http://test.com/cgi/d

how can i make a.html TraceId=1234
and b.css and c.js and cgi/d ParentSpanId=TraceId=1234 ?

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.