Have you ever added logging to your code to investigate a bug, waited for 45 minutes or more for the review and all the pipelines to complete, only to find out you still didn’t have enough information?
I have. I’ve spent countless hours during my career as a software engineer adding log statements to fix a bug combined with debug sessions with customers, only to find out that we didn’t log the right information. It’s frustrating - and yet, it happens every day!
To tackle this problem, I created WireQuery.
WireQuery allows you to capture, explore, and analyze data flowing in and out of your applications (e.g. the REST API calls including their headers, body, etc.). Meanwhile, it does not compromise confidentiality, because confidential fields are easily masked.
Combined with the possibility of creating front-end recordings as if they were a screen capture, WireQuery gives you all the information you need to reproduce (and therefore fix) virtually any bug.
In this post, I’d like to show you how you can set up WireQuery on your local machine and how to start using it with Spring Boot.
1. Setting up WireQuery
Setting up WireQuery on your local machine is relatively straightforward. It comes down to downloading two files from the WireQuery GitHub repository:
docker-compose.yml
nginx.conf
When these two files are in the same directory and you have Docker installed, simply run docker-compose up
in that folder. Wait a couple of minute until everything is loaded and head to localhost:8090
. You should now see a login screen.
Log in with admin
/ admin
and change your password. Then, head over to the Applications page and create a new application called “HelloWorld”. We're going to use this application in a short moment.
2. Creating a Web App
Now that WireQuery is set up, let’s create a simple Spring Boot project that interacts with it.
Head over to https://start.spring.io/ and add the following dependency: Spring Web
. Choose Gradle or Maven and make sure Java is selected and click Generate. Finally, open the generated project in your IDE.
Add the following dependencies to your project (you can find the latest versions of WireQuery on Maven Central:
In Maven:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-tracing-bridge-brave</artifactId>
</dependency>
<dependency>
<groupId>com.wirequery</groupId>
<artifactId>wirequery-spring-boot-3-starter</artifactId>
<version>0.1.216</version>
</dependency>
In Gradle:
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'io.micrometer:micrometer-tracing-bridge-brave'
implementation 'com.wirequery:wirequery-spring-boot-3-starter:0.1.216'
Let’s add a Controller to the project, called HelloController:
package com.example.demo;
import org.springframework.web.bind.annotation.GetMapping;
import com.wirequery.core.annotations.Unmask;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@GetMapping("/hello")
HelloResponse hello() {
return new HelloResponse("Hello, World!");
}
@Unmask
record HelloResponse(String message) {
}
}
Head back to the WireQuery dashboard. Click on the newly created application, the Actions button, "Show API Key" and copy its value. Then, add the following properties to the application.properties file, where <apiKey>
is replaced with the api key you just copied:
wirequery.connection.secure=false
wirequery.connection.host=localhost:9090
wirequery.connection.appName=HelloWorld
wirequery.connection.apiKey=<apiKey>
The final step is to implement a TraceProvider, which is used to identify the trace id of the current request.
package com.example.demo;
import com.wirequery.spring6.TraceProvider;
import io.micrometer.tracing.Tracer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class WireQueryConfig {
@Bean
public TraceProvider traceProvider(Tracer tracer) {
return () -> {
var span = tracer.currentSpan();
if (span == null) {
return null;
}
var context = span.context();
if (context == null) {
return null;
}
return context.traceId();
};
}
}
Finally, start the app. If all went well, both the app and WireQuery should now be working.
Let’s take WireQuery for a test run. Go back to WireQuery and type the following in the Explore bar: HelloWorld GET 2xx
. Then, open a separate tab and type: localhost:8080/hello
. If you now go back to WireQuery, you should see the request and response that was made by the browser. Congratulations, you have successfully set up WireQuery and integrated it with your app!
Of course, this is only the tip of the iceberg. Using WireQuery, you can:
- Create complex queries using operations like filter, map, flatMap and distinct to only capture what you need;
- Run queries in the background;
- Create templates that can start sessions consisting of multiple queries at once;
- Combine back-end data with front-end screen recordings;
- Trace a request multiple layers deep with the request and response bodies included;
- And much more.
For more information about WireQuery, head over to the official website or the GitHub repository.
Stay tuned for Part 2 in which I'll discuss how to connect the frontend to WireQuery!
Top comments (0)