- Ensure you have docker running
- Use cargo nextest run to run the tests
cargo nextest run
$ ps -e | grep tracerThis section outlines the requirements and setup necessary to use the S3 integration effectively. The S3 client supports flexible credential loading mechanisms.
-
AWS Credentials
- Ensure your AWS credentials are available in one of the following locations:
~/.aws/credentialsfile with the appropriate profiles.- Environment variables (
AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY).
- Ensure your AWS credentials are available in one of the following locations:
-
IAM Role (Optional)
- If running within an AWS environment (e.g., EC2, Lambda), you can use an IAM role to assume credentials automatically.
The S3 client initializes with the following options:
profile: Load credentials from a named profile in the~/.aws/credentialsfile.role_arn: Assume an IAM role to obtain temporary credentials.- Fallback: Automatically loads credentials from env when neither
profilenorrole_arnis provided.
-
Profile Name (
profile):- Set up a profile in your
~/.aws/credentialsfile. - Example:
[my-profile] aws_access_key_id = YOUR_ACCESS_KEY_ID aws_secret_access_key = YOUR_SECRET_ACCESS_KEY
- Pass the profile name as an argument to
new.
- Set up a profile in your
-
Assume Role (
role_arn):- Provide a valid
role_arnto assume an IAM role and retrieve temporary credentials. E.g:"arn:aws:iam::123456789012:role/MyRole"
- Provide a valid
-
Default Credentials:
- If no
profileorrole_arnis provided, credentials are loaded automatically based on the default AWS configuration.
- If no
-
Why use Docker with LocalStack
- To test the S3 integration, the client uses LocalStack, which is set up using Docker.
- The Docker Compose file is located in the root of the repo.
-
How to run Docker with LocalStack
- Ensure LocalStack is installed and running. You can start it using Docker:
docker run -d -p 4566:4566 -p 4571:4571 localstack/localstack
- Ensure LocalStack is installed and running. You can start it using Docker:
- You need to start Grafana Loki sperately: docker-compose up -d loki
- Check if it is running: docker ps | grep loki
-
Credential Resolution
- The function will panic if both
profileandrole_arnare provided. - It will also panic if no valid credentials are found during initialization.
- The function will panic if both
-
AWS Region
- Ensure the specified
regionmatches the location of your S3 buckets.
- Ensure the specified
- If you encounter the error:
failed to run custom build command for 'openssl-sys v0.9.103'or SSL-related issues, install the required dependencies:sudo apt install libssl-dev pkg-config
To speed up our CI pipeline, we utilize a custom Docker container registry on GitHub, known as the GitHub Container Registry (GCHR). This allows us to efficiently manage and deploy our Docker images.
-
Build the docker file
docker build -t rust-ci-arm64 -f Dockerfile . -
Tag the Docker Image
Tag your Docker image with the appropriate repository name:docker tag rust-ci-arm64 ghcr.io/tracer-cloud/tracer-cloud:rust-ci-arm64
-
Authenticate with the GitHub Container Registry
Use your GitHub token to log in to the registry. This step is necessary for pushing images:echo $GITHUB_TOKEN | docker login ghcr.io -u Tracer-Cloud --password-stdin
-
Push the Docker Image to the Registry
Push the tagged image to the GitHub Container Registry:docker push ghcr.io/tracer-cloud/tracer-cloud:rust-ci-arm64
-
Repeat Tagging and Pushing
If you need to tag and push the image again, you can repeat the tagging and pushing steps:docker tag rust-ci-arm64 ghcr.io/tracer-cloud/tracer-cloud:rust-ci-arm64 docker push ghcr.io/tracer-cloud/tracer-cloud:rust-ci-arm64
Ensure that your GitHub token has the necessary permissions to access the GitHub Container Registry.
Tracer requires a configuration directory. Create it with:
mkdir -p ~/.config/tracer/This file will hold the necessary settings, such as AWS Initalization type(Role ARN or Profile), API key, and any other runtime configurations.
touch ~/.config/tracer/tracer.tomlBefore running the tracer, you need to initialize it with an API key. Run:
cargo run setup --api-key "your-api-key"This step ensures that Tracer has the necessary authentication to send logs or traces to the backend.
This step sets up a custom Bash configuration to intercept and log relevant commands. It creates a .bashrc file inside the tracer config directory, defining aliases for monitored commands. This ensures that when a command runs, tracer logs its execution without interfering with normal operation.
Additionally, it redirects stdout and stderr to /tmp/tracerd-stdout and /tmp/tracerd-stderr, allowing users to track command outputs and errors. The setup persists across sessions by sourcing the custom .bashrc file in the user’s shell configuration.
cargo run apply-bashrcIf you’re running Tracer on an EC2 instance or a local machine that interacts with AWS, ensure your AWS credentials are set up correctly.
- Updating
tracer.tomlfor AWS IAM Roles (EC2):
Instead of using anaws_profile, modifytracer.tomlto specify the AWS IAM Role ARN you want to assume:aws_role_arn = "arn:aws:iam::123456789012:role/YourRoleName"
Tracer runs in the background as a daemon using the daemonize crate in Rust. This ensures it continues running after logout or system reboots.
- Monitor Daemon Logs for Errors
Since the tracer runs as a daemon, you won’t see its output in the terminal. Check logs for debugging:This file contains runtime errors if something goes wrong.tail -f /tmp/tracerd.err
The daemonize crate helps create system daemons in Rust by handling:
- Forking the process (so it runs in the background)
- Detaching from the terminal (so it doesn’t stop when you close the session)
- Redirecting logs to files (important for debugging)
- Setting permissions and working directories
A simple Rust program using daemonize might look like this:
use daemonize::Daemonize;
use std::fs::File;
fn main() {
let log_file = File::create("/tmp/tracerd.log").unwrap();
let error_file = File::create("/tmp/tracerd.err").unwrap();
let daemon = Daemonize::new()
.pid_file("/tmp/tracerd.pid") // Store PID
.chown_pid_file(true)
.working_directory("/") // Set working dir
.stdout(log_file) // Redirect stdout
.stderr(error_file) // Redirect stderr
.privileged_action(|| println!("Tracer started!"));
match daemon.start() {
Ok(_) => println!("Daemon started successfully."),
Err(e) => eprintln!("Error starting daemon: {}", e),
}
}This ensures Tracer runs continuously in the background.
Your Tracer agent should now be running as a daemon on your Linux machine. If you encounter issues, check logs in /tmp/tracerd.err. 🚀
To manage our PostgreSQL database schema and apply migrations, we use sqlx.
- Install sqlx CLI
If you haven’t already, install sqlx with:
cargo install sqlx-cli --no-default-features --features rustls,postgres- Creating a New Migration
To create a new migration, run:
sqlx migrate add <migration_name>This will generate two SQL files in the migrations/ directory: • {timestamp}<migration_name>.up.sql → Contains the SQL commands to apply the migration. • {timestamp}<migration_name>.down.sql → Contains the SQL commands to roll back the migration.
- Running Migrations
To apply all pending migrations to your database:
sqlx migrate runTo revert the last applied migration:
sqlx migrate revert
Note that the compiler won’t pick up new migrations if no Rust source files have changed. You can create a Cargo build script to work around this with:
This ensures that migrations are always detected and applied when building the project.
Here’s an improved version of the note with the clarification about embedding migrations:
- Embedding Migrations in Your Application
Did you know you can embed your migrations in your application binary? This allows your application to apply migrations automatically on startup.
After creating your database connection or pool, add:
sqlx::migrate!().run(<&your_pool OR &mut your_connection>).await?;When embedding migrations, the compiler won’t detect new migrations unless a Rust source file has changed. To ensure new migrations are always included, use a Cargo build script.