Post

A Battle to Debug

Special Thanks

Tiago Zanchi

Giuliano Ferrari

Paulo Godinho

Intro

On a Monday afternoon, we received a report from a player. He reported a problem when purchasing a DLC. After that, we started a saga to solve the bug. First, the tester would have to be able to reproduce on our device. Following the player’s steps, the bug was quickly reproduced. But what now? Few clues as to what could be happening. There was no way for us to see the logs (the device didn’t allow this to be possible in a simple way), which was essential to find a solution!

The first idea we had was to use a ready-made technology like Datadog, Datatrace, or even the Unity solution, “Cloud Diagnostics”. But this was all too robust for what we needed, and with an implementation that would take longer than we had. So, together with the team, we came up with a practical and quick solution, which I intend to comment on here in this post.

Designing the Solution

The idea was that every time the game used Unity’s Debug.Log function, it would do a web request to a simple server. When the request arrives on the server. It would create a file with the logs sent in the body of the POST.

We need to design our idea. So we use the perfect tool for that MIRO!

image

As we can see in the image, the idea was to be agile, to do everything locally. With that, we would use Cloudflare’s tunnel technology, which makes an “internet” connection with our local machine, in a SUPER SIMPLE way.

Tunnels

“In 2018, Cloudflare introduced Argo Tunnel, a private, secure connection between your origin and Cloudflare. Traditionally, from the moment an Internet property is deployed, developers spend an exhaustive amount of time and energy locking it down through access control lists, rotating ip addresses, or clunky solutions like GRE tunnels.”

“We built Tunnel to help alleviate that burden.”

“With Tunnel, users can create a private link from their origin server directly to Cloudflare without a publicly routable IP address. Instead, this private connection is established by running a lightweight daemon, cloudflared, on your origin, which creates a secure, outbound-only connection. This means that only traffic that routes through Cloudflare can reach your origin.”

https://blog.cloudflare.com/tunnel-for-everyone/

  • Creating the tunnel

Entering Cloudflare’s Zero Trust area, we can see the Tunnels tab:

Thus accessing the tunnel creation area.

After that, we give our tunnel a name. We install the .msi file provided by Cloudflare to run on our machine that will be the python server. Our “connector” as it is called by Cloudflare. We run the command with the tunnel token to make the connection:

Configure the hostname (Using the same port that we will set on the HTTP server. So that is mirrored) that automatically changes our DNS. And that’s it, tunnel created and running.

We used this to make the request reach our python HTTP server, running locally.

Python HTTP Server

We use the HTTP module that exists in python for requests and the JSON module to work with the received body:

We implement the do_POST function:

And we serve using a socket server.TCPServer on the indicated port:

So with the tunnel and the server running. Wait for the Unity request.

Unity Side

As seen earlier, each debug session creates a new file in the server folder. We then need to prepare the object that will be in the request body:

That was the object, serialized as a .json

Now let’s implement the function that was signed and called every time a Debug.Log() happens:

Now in OnEnable let’s sign it:

And as a good practice let’s remove the signature:

We add the script to a GameObject. In Awake we put a “DontDestroyOnLoad(this);”

That’s it

Now we have a link between the device and the developer. We added logs where we thought the error was, did a build, and the good news came, so we saw explicitly what was happening and the reason for the problem. The solution for capturing logs was done in less than two hours. We quickly had something valuable in our hands, something simple and effective that can be reused in any project and situation.

Then I saw a great opportunity for a post on my blog, sharing this idea so that other devs can debug when it isn’t possible to get logs more directly.

Author: Gabriel Przybysz Gonçalves Júnior - Backend Programmer GitHub: https://github.com/GabrielPrzybysz/battle-logs

This post is licensed under CC BY 4.0 by the author.