tracing_s3/
s3_helpers.rs

1use aws_sdk_s3::Client;
2use aws_sdk_s3::primitives::ByteStream;
3use aws_sdk_s3::types::ChecksumAlgorithm;
4
5pub async fn get_file_size(client: &Client, bucket: &str, key: &str) -> anyhow::Result<i64> {
6    let resp = client.head_object().bucket(bucket).key(key).send().await?;
7    Ok(resp.content_length.unwrap_or(0))
8}
9
10pub async fn append_to_file_multipart(
11    client: &Client,
12    bucket: &str,
13    key: &str,
14    // Ensure newline between each line
15    content_to_append: &str,
16) -> anyhow::Result<()> {
17    let offset = get_file_size(client, bucket, key).await.unwrap_or(0);
18    let content_to_append = content_to_append.as_bytes().to_vec();
19    client
20        .put_object()
21        .set_write_offset_bytes(Some(offset))
22        .checksum_algorithm(ChecksumAlgorithm::Crc64Nvme)
23        .bucket(bucket)
24        .key(key)
25        .body(ByteStream::from(content_to_append)) // Empty byte array
26        .send()
27        .await?;
28    Ok(())
29}
30
31#[cfg(test)]
32mod tests {
33    use crate::config::{Bucket, Config, CronIntervalInMs, Endpoint, ObjectSizeLimitMb, Prefix};
34    use crate::s3_helpers::{append_to_file_multipart, get_file_size};
35    use chrono::Utc;
36
37    #[tokio::test]
38    pub async fn append_to_file_test() {
39        let config = Config::new(
40            None,
41            None,
42            None,
43            Bucket(None),
44            Prefix("prefix"),
45            Endpoint(None),
46            ObjectSizeLimitMb(1),
47            CronIntervalInMs(1_000),
48        )
49        .await
50        .unwrap();
51        for _ in 0..5 {
52            let result = append_to_file_multipart(
53                &config.aws_client,
54                &config.bucket,
55                "check-file-exists.log",
56                &format!("hello world {}\n", Utc::now()),
57            )
58            .await;
59            println!("append_to_file_test result => {result:?}");
60        }
61    }
62}