Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[tracking issue] Client libraries in different languages #366

Closed
6 of 12 tasks
yurishkuro opened this issue Sep 1, 2017 · 43 comments
Closed
6 of 12 tasks

[tracking issue] Client libraries in different languages #366

yurishkuro opened this issue Sep 1, 2017 · 43 comments
Labels
enhancement help wanted Features that maintainers are willing to accept but do not have cycles to implement meta-issue An tracking issue that requires work in other repos

Comments

@yurishkuro
Copy link
Member

yurishkuro commented Sep 1, 2017

This issue tracks various implementations of tracing clients in different languages, either already available or under development.

As a guideline, the following is a rough outline for getting a new client out:

  1. setup new project, travis build, code coverage, release publishing, etc.
  2. implement basic tracer & span functionality with a simple 100% sampling & a configuration mechanism
  3. implement remote reporter with abstract sender
  4. implement UDP or HTTP sender or both
  5. implement crossdock integration tests
  6. implement other samplers (probabilistic, rate limiting)
  7. implement remote sampler that pulls sampling strategy from the agent
  8. implement adaptive sampler
  9. optionally other features like baggage whitelisting

Steps 1-4 are needed to get a minimal viable client. Steps 5-9 could be added later.

@gideonkorir
Copy link

Hi, trying to add a C# client porting from the Java client but still very early; I just started today.

Any feedback would be helpful

@rbtcollins
Copy link
Contributor

I note that neither Rust nor lua are on your list? Any plans to add them? (We are using openresty which leads to the Lua interest, and Rust - well Rust is cool :))

@yurishkuro
Copy link
Member Author

If someone implements then then we'd be glad to include in the official list. So far I haven't seen anyone asking/trying, so no plans.

Also, we're working on a c++ client, I wonder if some of the languages can be done as wrappers on top of that.

@rbtcollins
Copy link
Contributor

I'd very much encourage writing such a low level client in a more modern systems language like Rust : more cleanly bindable to C (no need to explicitly opt out of the rtti support or pull in the C++ support libraries), and very very safe.

We have some components that are nginx+openresty, so we have interest in Lua (language) support + openresty bindings : I am thinking we'll just implement the whole store in Lua rather than have to surface span data from a C++ module back up through nginx's C core and then in to Lua.

@mfilotto
Copy link

Anything yet for Javascript in browser ?

@yurishkuro
Copy link
Member Author

Nobody is working on it right now (jaegertracing/jaeger-client-javascript#1 - help wanted)

@isaachier
Copy link
Contributor

@rbtcollins I wonder what the performance will look like compared to just wrapping the C++ client in a luarocks package and using that.

@yurishkuro I have also been wondering what it would take to wrap all the client languages around the C++ client. Here is the plan as of now:

Java: JNI (no one likes it though, so IDK)
Go: cgo
Python: C module
Node.js: C++ add-on
JavaScript: Emscripten
Ruby: C++ extension
PHP: C module
Lua: C++ bindings

The easiest, by far, is Lua (I have some experience here). The others might be harder. On the flip-side, I wonder how easy it is to do this very same thing with the Go client once it is compiled. Any thoughts and/or experience here would be greatly appreciated.

@yurishkuro
Copy link
Member Author

Yes, we discussed the possibility, but until we actually try with some languages it's hard to see all pros & cons (and there are a lot of cons to wrapping).

@rbtcollins
Copy link
Contributor

@isaachier I have zero interest in debugging interactions between C++ RTTI and exceptions, and any host language. We need anything that is going to be surfaced in such a way to be rock solid and have no corner cases that will make it a liability rather than an asset.

rustlang or C would make good 'lowest common denominator' languages, if having a bridge mechanism to a single set of implementation backends is desirable - they can both be bound to with no runtime support, without having to disable language features (unlike e.g. C++ where the default requires runtime support).

That said, I fully expect every non-trivial language to demand, and get, 100% native bindings. There's nothing in Opentracing/Jaeger/Thrift that would make native support hard/infeasible.

On the list of languages you've got, I can specifically say:

  • that we could tolerate JNI, but would very much prefer to avoid it because of the overheads involved in something in our core request path.
  • Python - C modules make deployment harder, so would stay with the current implementation.
  • Javascript - emscripten is awesome and clever and huge. Not even going to consider it. We'd probably use the zipkin endpoint so that we can have a super minimal implementation with no Thrift involved at all.
  • Lua in the context of openresty: Would very much prefer not to have to install additional modules into nginx over what the stock docker images contain, so yeah - again, native is super appealing.

@isaachier
Copy link
Contributor

@rbtcollins interesting point about Rust vs. C++. I am actually amazed to hear that you prefer Rust to C++ in the area of language bindings. I had always heard the compiler support for Rust is much more limited than C++, and neither compare to C, which has a compiler for almost every conceivable platform. But I do understand the concern. For that reason, I think gRPC was motivated to write its core library in C++ without any STL (making it pretty much C).

Meanwhile, I think you are correct that the "best" thing would be to have a native library for each and every language. But I'm interested in hearing your opinion for the following difficulties:

  • Some languages just do not have good multithreading support (i.e. Python). A C module would perform much better than anything in the native language.
  • How do we implement changes consistently once the number of languages goes up? As of now, our Python client still uses the older Zipkin format instead of our better Jaeger format. The main reason is the cost associated with maintaining multiple client libraries.
  • Although C modules/packages are more difficult to deal with than their native language counterparts, almost every major package manager has a good way of dealing with this, be it pip, luarocks, or gem. How difficult is it using these tools?
  • Individual, language-specific libraries are by definition less tested. By uniting all of the languages with a common core library, we can guarantee the core itself is bug-free.

@yurishkuro
Copy link
Member Author

I am also interested in another consideration - if we take our Python client and reimplement it as a wrapper on top of C++ client, how much functionality will be removed from the pure-Python part of the combo? We still have to implement the OpenTracing API, but probably concerns like different samplers, retrieving samplers from the agent, and the whole async span reporting could be moved to C part.

Although C modules/packages are more difficult to deal with than their native language counterparts, almost every major package manager has a good way of dealing with this, be it pip, luarocks, or gem.

I tend to agree with that, not so much based on experience, but on the fact that out Python/Node clients already depend on modules like thriftrw which use C bindings and require compilation during install. But we only use Linux/MacOS, so don't know how well this would work on other platforms.

@isaachier
Copy link
Contributor

About the bindings, there is a certain amount of bridge code for each language. I think it comes down to how much you want the code to look idiomatic (i.e. avoiding calling Python functions with mysterious handle objects, manual resource management, and the like). I'd advocate not using the language itself to implement span objects etc. because of the repetition and the memory overhead. This takes some clever coding but isn't too hard.

The build shouldn't really be a concern. The only thing I worry about is the C vs. C++ debate. Worst case scenario, we could refactor some of the core C++ types to C structs. The only reason I haven't yet considered that seriously is that there is no OpenTracing C API, and if that API is released down the line, it would probably invalidate any Jaeger-specific code I write now.

@yurishkuro
Copy link
Member Author

I'd advocate not using the language itself to implement span objects etc. because of the repetition and the memory overhead. This takes some clever coding but isn't too hard.

I don't see how you'd do that since the end user is still going to interact with object-oriented OpenTracing API. Unless you're saying that you can create C-bound objects that look like normal host language objects to the end user.

@isaachier
Copy link
Contributor

Ya essentially all fields are in the C struct and you point all setters and getters to conversion functions so they get a pretty Python/Ruby/Lua value. If you want to be really efficient you can do this at multiple levels so there is truly no-copying/allocation beyond that initial struct. For example, consider using a custom tag list struct instead of copying tags into a new Python list. Then implement Python list operations for the tag list struct. The client doesn't realize it isn't a native list because it implements the sequence interface.

@rbtcollins
Copy link
Contributor

@isaachier by compiler support for rust, I'm not sure what you're referring to. Rust was built to integrate with Firefox's core - thats a primary use case for it (and it has delivered many of the major perf improvements in recent firefox :)).

What memory overhead are you worried about with native implementations? Remember that when you have bindings you end up with separate arenas for the external objects, which can spread memory footprint out somewhat.

@isaachier
Copy link
Contributor

I mean embedded systems. I know there is interest in tracing for IoT devices. Rust may not target these devices as well as C++. Memory isn't the main consideration here. More of a bonus.

@rbtcollins
Copy link
Contributor

rbtcollins commented Nov 2, 2017 via email

@isaachier
Copy link
Contributor

OK did some research and cannot find much evidence that C is inherently better for bindings than C++ with and C wrapper API (i.e. extern "C"). Please let me know if you have a good source I can read on this issue.

@taoso
Copy link

taoso commented Dec 2, 2017

Hi @yurishkuro , would you like to accept the lvht/jaeger-php as the official PHP client of Jaeger?

@yurishkuro
Copy link
Member Author

@lvht let's discuss on #211

@autodidaddict
Copy link

Have not tried this, but here is a Rust Jaeger client built on top of another Rust opentracing API: rustracing_jaeger

@yurishkuro yurishkuro added enhancement help wanted Features that maintainers are willing to accept but do not have cycles to implement roadmap labels Dec 23, 2017
@isaachier
Copy link
Contributor

BTW @rbtcollins Rust just announced they will be working on better embedded support this year. https://internals.rust-lang.org/t/announcing-the-embedded-devices-working-group/6839

@ldeveloperl1985
Copy link

is there any Lua client or any other way to use jaeger in Lua language?

@isaachier
Copy link
Contributor

isaachier commented Jun 28, 2018

@ldeveloperl1985 that largely depends on whether or not OpenTracing decides to support Lua. Also, the issue of many different dialects makes the situation much more difficult. Which version of Lua do you use? Is it original Lua or LuaJIT?

@ldeveloperl1985
Copy link

I've used kong 0.11v. which uses Lua 5.1 and LuaJIT 2.1.0

@isaachier
Copy link
Contributor

Kong is probably the primary use case. I am not familiar with that version, but does it support 64 bit integers? My problem is maintaining compatibility across several versions of Lua.

@ldeveloperl1985
Copy link

You can easily maintain compatibility across several versions of LUA. Lua is a dynamically typed language. There are no type definitions in the language; each value carries its own type.

@isaachier
Copy link
Contributor

That is much easier said than done. I know for a fact that 64 bit integers are only supported in >= 5.3. Also, I believe the C API has inconsistencies across minor versions and LuaJIT.

@yurishkuro
Copy link
Member Author

@ldeveloperl1985 @isaachier let's move Lua discussion to #898

@jalberto
Copy link

I suggest to add Elixir to the list :)

@isaachier
Copy link
Contributor

@jalberto I'm really hoping to move away from more client maintenance. We can probably use C to glue together an Elixir/Erlang client.

@jalberto
Copy link

@isaachier so maybe every client (backend) should be a wrapper to C client to have features parity. If some clientes are native, adn others are just wrappers, there is a risk to split features set.

@isaachier
Copy link
Contributor

There is already significant feature split among the clients. And if I thought anyone would want to use C other than myself, I'd agree with you about using the same C library for all clients. However, some languages make this approach easier than others. For example, I have heard Java's JIT makes calling a native function significantly slower than calling the equivalent Java code.

@jalberto
Copy link

well, using a wrapper/binding to a different lang will always create an impact, in particular in this kind of libs that need to be called very often.

In other hand to use a C-binding-wrapper may cause some headache dependencies-side or deployment-side even with docker (imagemagick in ruby or perl is a good example). Also docker images using alpine or any version of non-glibc can be tricky at least.

IMHO as there is not perfect solution I suggest to avoid hybrid solutions (that will increase troubles surface), I suggest to go one side or the other:

  • use a C lib/sys-cmd+wrapper for every backend client
  • or create a client per language
  • or support opentracing clients

To have some langs with native clients and other with a wrapper can icnrease th eamount of work instead of reducing it, also it may:

  • 1st class vs 2nd class clients (updates, new features, etc)
  • features disparity
  • outdated clients
  • etc

@isaachier
Copy link
Contributor

I'll agree that the C based clients are going to be second class, mostly because they aren't languages we ever use. The notable exception here is C# where an external contributor volunteered to maintain it. Among the Jaeger developers at Uber, I don't believe C# is our top priority.

Regarding packaging, people complain about it, but whether you like it or not many libraries rely on C bindings because it just isn't worth reinventing the wheel every time. As long as some care is taken in the approach to wrapping it, I think it's a viable solution.

Finally, I'm not sure what you mean by "support opentracing clients." Interestingly, @rnburn of OpenTracing C++ just created a Lua tracer that is implemented from an underlying C++ tracer and exposed through bindings.

Just know, if there are tiers of clients, Go is clearly the focus and everything else is secondary.

@yurishkuro
Copy link
Member Author

Another major benefit of using wrappers around a C-lib is that those wrappers only need to be implemented once in the OpenTracing community.

@jalberto
Copy link

by supporting OT clients I mean, to "ditch" jaeger client in favour of OT client and join the effort there

@isaachier
Copy link
Contributor

@jalberto Jaeger is an implementation of the OT specification. There is no concrete OT client that I know of in open source other than Jaeger. OT is just an interface, not an implementation.

@jalberto
Copy link

My mistake, I thought the clients here: http://opentracing.io/ has a different code base.

In that case: https://github.com/derailed/ex_ray

@isaachier
Copy link
Contributor

Feel free to use another client. If you know of others interested in supporting this client please let us know.

@jpkrohling jpkrohling added the meta-issue An tracking issue that requires work in other repos label Apr 2, 2019
@yurishkuro yurishkuro changed the title Client libraries in different languages [tracking issue] Client libraries in different languages Nov 2, 2019
@andrewbanchich
Copy link

Looks like there is a client for Rust now: https://github.com/sile/rustracing_jaeger

@altexdim
Copy link

altexdim commented Apr 1, 2021

Hey everyone
What's the best library to use with Jaeger 1.22 for PHP?

@yurishkuro
Copy link
Member Author

Per #3362, we're sunsetting Jaeger clients.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement help wanted Features that maintainers are willing to accept but do not have cycles to implement meta-issue An tracking issue that requires work in other repos
Projects
None yet
Development

No branches or pull requests