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
10async 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)
18        .await
19        .unwrap_or_else(|_| 0);
20    let content_to_append = content_to_append.as_bytes().to_vec();
21    client
22        .put_object()
23        .set_write_offset_bytes(Some(offset))
24        .checksum_algorithm(ChecksumAlgorithm::Crc64Nvme)
25        .bucket(bucket)
26        .key(key)
27        .body(ByteStream::from(content_to_append)) // Empty byte array
28        .send()
29        .await?;
30    Ok(())
31}
32
33#[cfg(test)]
34mod tests {
35    use crate::config::{Bucket, Config, CronIntervalInMs, Endpoint, ObjectSizeLimitMb, Prefix};
36    use crate::s3_helpers::{append_to_file_multipart, get_file_size};
37    use chrono::Utc;
38
39    #[tokio::test]
40    pub async fn append_to_file_test() {
41        let config = Config::new(
42            None,
43            None,
44            None,
45            Bucket(None),
46            Prefix("prefix"),
47            Endpoint(None),
48            ObjectSizeLimitMb(1),
49            CronIntervalInMs(1_000),
50        )
51        .await
52        .unwrap();
53        for _ in 0..5 {
54            let result = append_to_file_multipart(
55                &config.aws_client,
56                &config.bucket,
57                "check-file-exists.log",
58                &format!("hello world {}\n", Utc::now()),
59            )
60            .await;
61            println!("append_to_file_test result => {result:?}");
62        }
63    }
64}