{"id":19992666,"url":"https://github.com/openzipkin/zipkin4net","last_synced_at":"2025-05-15T12:04:34.688Z","repository":{"id":39873634,"uuid":"81463930","full_name":"openzipkin/zipkin4net","owner":"openzipkin","description":"A .NET client library for Zipkin","archived":false,"fork":false,"pushed_at":"2023-12-15T15:48:29.000Z","size":741,"stargazers_count":339,"open_issues_count":37,"forks_count":88,"subscribers_count":20,"default_branch":"master","last_synced_at":"2025-04-24T06:36:33.136Z","etag":null,"topics":["openzipkin","zipkin"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/openzipkin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-02-09T15:22:47.000Z","updated_at":"2025-04-09T06:16:54.000Z","dependencies_parsed_at":"2024-06-18T12:21:01.597Z","dependency_job_id":null,"html_url":"https://github.com/openzipkin/zipkin4net","commit_stats":{"total_commits":336,"total_committers":33,"mean_commits":"10.181818181818182","dds":0.5386904761904762,"last_synced_commit":"63976c5325f36c38df3a3b237f10a9ac2e33f482"},"previous_names":["criteo/zipkin4net"],"tags_count":23,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openzipkin%2Fzipkin4net","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openzipkin%2Fzipkin4net/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openzipkin%2Fzipkin4net/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openzipkin%2Fzipkin4net/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/openzipkin","download_url":"https://codeload.github.com/openzipkin/zipkin4net/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254337612,"owners_count":22054253,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["openzipkin","zipkin"],"created_at":"2024-11-13T04:52:15.854Z","updated_at":"2025-05-15T12:04:29.672Z","avatar_url":"https://github.com/openzipkin.png","language":"C#","funding_links":[],"categories":["C\\#","C# #"],"sub_categories":[],"readme":"[![Gitter chat](http://img.shields.io/badge/gitter-join%20chat%20%E2%86%92-brightgreen.svg)](https://gitter.im/openzipkin/zipkin)\n\n\n# Zipkin4net\n\nA .NET client library for [Zipkin](http://zipkin.io).\n\n## Build status\n\n[windows-build-badge]: https://travis-ci.org/openzipkin/zipkin4net.svg?branch=master\n[windows-build]: https://ci.appveyor.com/project/fedj/zipkin4net\n\n[linux-build-badge]: https://travis-ci.org/openzipkin/zipkin4net.svg?branch=master\n[linux-build]: https://travis-ci.org/openzipkin/zipkin4net\n\n|Linux|Windows|\n|:------:|:------:|\n|[![][linux-build-badge]][linux-build]|[![][windows-build-badge]][windows-build]|\n\n\n## What it provides\n\nIt provides you with:\n- Zipkin primitives (spans, annotations, binary annotations, ...)\n- Asynchronous trace sending\n- Trace transport abstraction\n\n## Basic usage\n\n### Bootstrap\n\nThe easiest way to use the library is the following\n\n```csharp\nvar logger = CreateLogger(); //It should implement ILogger\nvar sender = CreateYourTransport(); // It should implement IZipkinSender\n\nTraceManager.SamplingRate = 1.0f; //full tracing\n\nvar tracer = new ZipkinTracer(sender);\nTraceManager.RegisterTracer(tracer);\nTraceManager.Start(logger);\n\n//Run your application\n\n//On shutdown\nTraceManager.Stop();\n```\n\nYour zipkin client is now ready!\n\n### Play with traces\n\nTo create a new trace, simply call\n\n```csharp\nvar trace = Trace.Create();\n```\n\nThen, you can record annotations\n\n```csharp\ntrace.Record(Annotations.ServerRecv());\ntrace.Record(Annotations.ServiceName(serviceName));\ntrace.Record(Annotations.Rpc(\"GET\"));\ntrace.Record(Annotations.ServerSend());\ntrace.Record(Annotations.Tag(\"http.url\", \"\u003curl\u003e\")); //adds binary annotation\n```\n\n### Transport\n\nThe transport is responsible to send traces to a zipkin collector.\n\n#### HTTP transport\n\nWe provide you with an [HTTP transport](Src/zipkin4net/Src/Transport/Http/HttpZipkinSender.cs). Just create it with the zipkin collector url (i.e. if you test locally, you'll probably end up with something like 'http://localhost:9411') and pass it to the creation of the [ZipkinTracer](Src/zipkin4net/Src/Tracers/Zipkin/ZipkinTracer.cs) and you're set.\n\n#### Custom transport implementation\n\nThe implementation is really easy to do. All you have to do is to implement a Send(byte[]) method.\nFor example, if you want to send traces through Kafka and assuming you have a kafka producer, you should write\n\n```csharp\nclass KafkaZipkinSender : IZipkinSender\n{\n  private readonly IKafkaProducer _producer;\n  private const string Topic = \"zipkin\";\n\n  public KafkaZipkinSender(IKafkaProducer producer)\n  {\n    _producer = producer;\n  }\n\n  public void Send(byte[] data)\n  {\n    _producer.produce(Topic, data);\n  }\n}\n```\n\nWe internally use [Kafka-sharp](https://github.com/criteo/kafka-sharp).\n\n### Span creation\n\nZipkin is designed to handle complete spans. However, an incorrect usage of the library can lead to incomplete span creation. To create a complete span, you need a pair of matching annotations in the following list:\n\n- ServerRecv and ServerSend annotations\n- ClientSend and ClientRecv annotations\n- LocalOperationStart and LocalOperationStop annotations\n- ProducerStart and ProducerStop annotations\n- ConsumerStart and ConsumerStop annotations\n\n### When are my traces/spans sent?\n\nA span is sent asynchronously to the zipkin collector when one of the following annotation is recorded:\n- ServerSend\n- ClientRecv\n- LocalOperationStop\n- ProducerStop\n- ConsumerStop\n\nwith the matching opening annotation specified above (matching means same (traceId, spanId, parentSpanId)).\n\nA [flushing mechanism](#flush-mechanism) regurlarly checks for incomplete spans waiting in the memory to be sent.\n\n## Advanced usage\n\n### Monitor the tracer itself\n\nThe library comes with few handy tricks to help you monitor tracers\n\n#### Metrics\n\nZipkinTracer can be created with an implementation of [IStatistics](Src/zipkin4net/Src/Tracers/Zipkin/Statistics.cs) interface. This is useful if you want to send various metrics to graphite.\nWe update four metrics:\n\n| Metric          | Description                                                             |\n| --------------- | ----------------------------------------------------------------------- |\n| RecordProcessed | The number of annotation, binaryAnnotations, ... recorded by the tracer |\n| SpanSent        | The number of span successfully sent                                    |\n| SpanSentBytes   | What went on the network                                                |\n| SpanFlushed     | The number of span flushed                                              |\n\nSince the library is meant to have almost no dependency, you'll have to write the implementation that sends these metrics to graphite for example.\n\n#### Tracers for testing and debugging purposes\n\nWhen integrating this kind of library, it can be useful to know that we called it correctly.\n\n##### Debugging\n\n[ConsoleTracer](Src/zipkin4net/Src/Tracers/ConsoleTracer.cs) writes every record it gets on the console (annotations, service names, ...).\n\n##### Unit/Integration test\n\n- [InMemoryTracer](Src/zipkin4net/Src/Tracers/InMemoryTracer.cs) keeps every record in a queue. It is useful when a mock tracer is not enough.\n- [VoidTracer](Src/zipkin4net/Src/Tracers/VoidTracer.cs) drops records. It is useful when you don't need tracing in tests.\n\nPlease also note that the default sampling is 0 meaning that by default, tracing is disabled. You should either set the sampling to 1.0 (to be deterministic) or force the trace to be sampled.\n\n### B3 Headers propagation\n\nIf your services communicate through HTTP, we provide you with headers injection and extraction ([ZipkinHttpTraceInjector](Src/zipkin4net/Src/Transport/ZipkinHttpTraceInjector.cs) and [ZipkinHttpTraceExtractor](Src/zipkin4net/Src/Transport/ZipkinHttpTraceExtractor.cs)). It will allow you to add headers in HTTP requests between your services.\nThe headers are zipkin standard headers but you can also implement yours with interfaces [ITraceInjector](Src/zipkin4net/Src/Transport/ITraceInjector.cs) and [ITraceExtractor](Src/zipkin4net/Src/Transport/ITraceExtractor.cs).\n\n### Flush mechanism\n\nWe implemented a safety mechanism in the library in order to avoid any memory footprint explosion. Spans can remain in memory if the user doesn't record the matching annotation to complete the span, leading to [a memory leak](#span-creation). To avoid it, we added a safety that removes these spans after 60 seconds.\n\n### Force sampling\n\nYou can force a trace to bypass sampling. It is useful for tests but can also be useful if you want to trace specific requests depending on the context.\n\n```csharp\nTrace.ForceSampled();\n```\n\nIf you want to do that in production, we highly recommend too wrap your [IZipkinSender](Src/zipkin4net/Src/Tracers/Zipkin/IZipkinSender.cs) implementation with the [RateLimiterZipkinSender](Src/zipkin4net/Src/Tracers/Zipkin/RateLimiterZipkinSender.cs). It will throttle traces based on a time-window pattern.\n\n### Trace context\n\nPassing the trace context accross every API can be very cumbersome and doesn't bring any real added value. It's also a bit painful to implement a working solution if you have async code. That's why we implemented [TraceContext](Src/zipkin4net/Src/TraceContext.cs) which relies on .Net [CallContext](https://msdn.microsoft.com/fr-fr/library/system.runtime.remoting.messaging.callcontext(v=vs.110).aspx) to carry traces over the execution path.\n\nBy setting\n\n```csharp\nTrace.Current = myTrace;\n```\n\nYou will be able to retrieve it, even if you have async code in between. It means that it will follow the sync/async path of your request.\nSince it can be a bit tricky, please use it with caution and if you know what you're doing.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenzipkin%2Fzipkin4net","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopenzipkin%2Fzipkin4net","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenzipkin%2Fzipkin4net/lists"}