 Okay, so hi everyone. So many miss you. Today I will be presenting about tracing simplified and introductions to microservices observability with deeper. So, next, this is more about me currently I'm a master student in data science at the University of Edinburgh. I'm also a CSF ambassador and my past experience mostly with the two software engineering. This is my previous employer, there's like motionals, Spotify and follow up. And this is today's agenda. First, I want to have some kind of like introductions to observability. Next, we will try to kind of like understand tracing and the third one will be Some kind of like reminder or offer feel about deeper. Next, we will try to kind of like implement tracing with deeper. For the last thing will be Q&A sessions and passing remarks. And this is more about like introductions to observability. So we often heard about observability in the system and microservices, right. So why we often heard about things what's important for like observability to come into picture. So observability is actually the key in managing complex microservices architecture because it can provide insight into how different parts of the system are performing and interacting. And effective observability actually helps in identifying and resolving issues quickly and showing the system reliability and performance. And there is like three different components for observability. The first one is metrics. Metrics is more like numerical data that can provide insights into the performance of the system. Example includes response time, error rates and resource utilizations. Second one is logs. Logs are records of events that occurs within applications. And this usually come into picture when we are trying to debug and then try to kind of like understand the system behavior of the time. Next we have tracing. Tracing actually tracks a journey of a request across various microservices. And it helps in identifying bottlenecks and understanding the flow of requests through the system. So what's the benefit of observability? It will bring confidence especially in a complex cloud environment. It can also improve organizational alignment. For example, we have a request to try to kind of like improve the system or we get like a feedback from the users that our system is getting slower, right? To be able to narrow down what kind of like things that actually become a bottleneck, we need to gather more data. And by using a tracing we can actually, our observability in general, we can narrow down the components that causing like the slow responses and how we can actually get like a faster feedback loop when trying to kind of like improve our system performance. And because it's easier for us to narrow down problems when an issue is actually happening, so it will also help us in the terms of like preventing unnecessary down time or making like a down time is kind of like longer because we don't know how to kind of like deploy the problems that's actually happening across our system. Next, we want to kind of like understand what's actually tracing is. So traces actually shows the request path. They tracks where the request actually goes and which parts of the system it interacts with. Traces actually resemble loads, but they are kind of like a special kind of blocks, which records each steps of a request journey. And traces refills work details. They show how much work is done at each step of the system. And traces actually maintain the order. They are using a special rules called happens before semantics to keep the events in correct sequence showing which actions lead to the others. In short traces are like sorry, both set nearest entire journey of a request through a different parts of the system from start to finish and in the correct order. So this is like example on how sample request actually works, right? Imagine that we have four different components, which are being represented as alphabet here, A, B, C, and D. And then we have one external component, which is radius that being called by surface B. We can see that the request actually started from A, and it will actually chaining down into external dependencies, which is radius and then other components like C, B, and D. Then next we will end up with various information for each of the set invocations, as well as the total journey between the first incoming request to the result. And the first component of the distributed system set being taught here during the life cycle of request actually represented as a direct statistical graph. This is how trace actually looks like. A trace is actually represented as spans. We can see here span A is actually a span and span B is a child of spin B. So whenever request is actually like coming, then we will generate a new span here, and we can gather like informations from each of the span and propagate it back to like the root span, just we will get like the whole trace. So what is the challenge is when we try to kind of like do tracing, first one is complexity, because there is a distributed nature of micro surfaces that can make tracing actually challenging as a single transaction may span multiple surfaces. And then second one is consistency. Ensuring consistent and accurate data collections across different surfaces is crucial but difficult because it will add more complexities when we try to collect all of the information that we need. Next, we will have like overhead, because implementing tracing can actually add overhead to the system, which needs to be managed effectively to avoid bottleneck on the tracing system itself. So we have like deeper into the picture right now, right? So Dapper actually allows us to use any code or frameworks to our liking and then perform HTTP API or CRPC API to access surface implications, set management, messaging broker, actual secrets configurations, and so on by using the Dapper runtime. And then we can deploy this on top of any cloud or edge infrastructure, like Azure, AWS, Google Cloud, Alibaba, Kubernetes, virtual or even physical machine. Such is actually really flexible for us to do things to our liking, right? Then how actually there's a little bit of the tracing works in Dapper. Imagine that we have like two different surface components here called A and B. And for each surfaces, it will be connected into its own sidecar container, which in turns are running Dapper, right? So when we are creating like a surface invocation or trying to do some kind of like events, then Dapper will release this or will emit this tracing into like any monitoring tools that we want to use. For example, like Zipkin, Jaker, Neuraly, or any kind of like Fender, like Datadoc, and so on. Yeah, for the monitoring, from the monitoring tools, we can visualize how the chain of call from like a single request is actually happening or interacting with each others. We also can get information or like can infer the information on when we actually having some kind of like extra dependences. And this form is actually a pop-up component by using a Kafka. So we already know how distributed tracing in Dapper actually works, right? It's actually using the Dapper runtime on each of the sidecar container attached to each of the surfaces. How it is actually being generated by Dapper? If you are using Dapper, you will get this feature by default, meaning that Dapper will generate a trace for you. And it will be in the form of W3C tracing specifications, which is actually included as a part of open telemetry, or OTEL. And Dapper will be the one that actually generate and propagate the context header for the obligations. Or if let's say you are sending a request from a non-Dapper environment, then it will propagate any kind of like custom user-provided context header and put it into like any monitoring tools of our liking, which is quite flexible, because you don't need to migrate all of your surfaces into like a Dapper environment. But if let's say you want to kind of like implement or like incrementally changing your system by creating, for example, like still using the legacy system and creating your own like user-provided context headers for the spans and then calling like leather surfaces, which actually using Dapper, you can still pass this information to like your leather system. Next, what kind of like scenarios that being supported by Dapper? So Dapper, as we already know, Dapper will generate the trace context and there might or might not be a need for you to propagate the trace context to another surface. If let's say you want to use the same spans for multiple surfaces, then you will need to kind of like propagate the context header by your own. But if let's say you decide just kind of like let each of the surface communications to have its own span, then there is no need for you to kind of like propagate the context header by yourself. And if let's say you decide to generate the trace context from outside of Dapper environment and then doing some kind of like some invocations to your Dapper runtime, then you can actually generate this trace context by using a standard open telemetry SDK, any kind of like vendor SDK or W3C trace context that you can create by your own. And yeah, so how actually trace in context looks like. There is two different things that actually exist within like tracing context in order to be able to support interoperability and vendor specific extensibility. The first one is trace parents. Trace parents actually describes positions of incoming requests in its trace graph in a portable fixed length format. So every tracing tool must probably set trace parents even when it only relies on vendor specific informations in trace state. Trace state extends trace parent with vendor specific data represented by a set of name and fairly pairs. This trace state is actually optional. Right. This is more like adding any kind of like additional information that you want to have on your trace. Next, how trace parents actually looks like. So there is like four different information set you will have inside of like trace parents. The first one is versions. Trace ID, parent ID and trace flags. And it will be in the forms of like past 16 format. You can see that each of the information set will have here is separated by a dash. And for the trace flags, it is kind of like sampled by the trace generation itself. And next, this is how trace state actually looks like. The trace state will contains any kind of like opaque values in any forms of like keys and values there. So let's say we want to kind of like add two different keys and values there here, then it will actually being like presented as like opaque values without any kind of like any need to decode it into any of the forms. So we already know that if let's say we want to for some kind of like custom usage, right? We want to kind of like pass through a same spans offer several different surfaces. We will need to pass the context header by ourself. First one, we will need, of course, a trace parent slide because it is needed for all of different surfaces to sorry for all of different phases to have like transparent haters. And if we want to we also can get the trace state haters. So that's only two things that we need. And the header name is actually just the same as the W3C schema that we already discussed before. And for the gRPC instead of like Dapper, it will have different headers. And the header name is actually gRPC's trace being the header. So we will have here a quick start for self hosted mode. I'm sorry, but I can't do any kind of like emails because somehow there is some kind of like problems with my laptop. So this is actually being taken from a quick start from Dapper. And code is actually written in Python. And we don't actually need to do anything for sake of like imaging the traces by ourself. What we need, of course, is having like a Dapper installed on our environment. And we will need to kind of like run Dapper in it, which will generate YAML configuration file. If let's say we run it in the Unix live environment, it will be within our home slash dot Dapper slash config dot YAML. And if we run it for Windows, then we will have it inside of like our user profile backslash dot Dapper backslash config dot YAML. And this is like the content of the configurations. And it will by default using a Zipkin. And we will need to kind of like provide endpoint address. And this is like the default configurations that we will have. And next we will need to kind of like launch the open Zipkin docker container, because it is where we will actually push all of our phrases. And we will be able to kind of like get visualizations for our phrases here. And if let's say the applications is being launched by Dapper run. And this Dapper run will by default reference config file within like our environment. Of course it's if it's kind of like Unix live, then it will be on our home. And if it's kind of like Windows, then it will be within our user profile. And if let's say we decide to kind of like offer right the configurations, we only need to kind of like pass test test config param. And we will need to kind of like launch the quick start story. And after that, we need to run the code. There is some kind of like Python code and then no JS code as well. And once the app is actually running, we need to make surface infogations using Dapper infog with provided request content within the free post story. And that's if let's say we already do the invocations, then we can actually get the get the phrases from like our visualization tools, which is using the Zipkin open Zipkin, right? There is two different mechanisms in order to kind of like access the open Zipkin. The first one is of course using the Zipkin UI, which can be accessed within the local host with the part of 94011, right? And then we can also call in the Zipkin by using Zipkin API using a call. And we need to kind of like specify the span name. And then we'll output it into output address on. And we can take a look into what kind of information set we will have within this result right. First one is of course like trace ID, a kind name. And then we will get some kind of like information, right? Surface name, of course. And API endpoint, which being accessed when we are using Dapper infog, the status code protocol and the search subscriptions and so on. So basically that's it. And if let's say we decide to kind of like use Kubernetes on like a cloud infrastructure, then we should make sure that the Kubernetes cluster already have like Dapper install. And we are ensuring that each of like our surfaces have a Dapper sidecar container which kind of like emitted traces. And we can also configure on what kind of like get tools that we want to have as the monitoring tools in general. Okay, so basically that's it. And there is like a few Dapper resources that you can access. First one is of course the conditions within Dapper.io. And we also have like a channel called Dapper in YouTube. And this is like the tutorials that we discussed in the sessions, which is like Dapper Quick Starts. And we also have like a Discord for Dapper community. And the last but not least is an X account for Dapper, which is Dapper Dev. Okay, if there is any kind of like questions, feel free to like ask it in the chat. Yeah, basically that's it. Thank you for your time.