1use aws_sdk_s3::Client;
2use aws_sdk_s3::primitives::ByteStream;
3use aws_sdk_s3::types::ChecksumAlgorithm;
4
5pub struct S3Helpers {}
8
9impl S3Helpers {
10 pub async fn get_file_size(client: &Client, bucket: &str, key: &str) -> anyhow::Result<i64> {
21 let resp = client.head_object().bucket(bucket).key(key).send().await?;
22 Ok(resp.content_length.unwrap_or(0))
23 }
24 pub async fn append_to_file(
37 client: &Client,
38 bucket: &str,
39 key: &str,
40 content_to_append: &str,
41 ) -> anyhow::Result<u64> {
42 let offset = Self::get_file_size(client, bucket, key).await.unwrap_or(0);
43 let total_len = offset as u64 + content_to_append.len() as u64;
44 let content_to_append = content_to_append.as_bytes().to_vec();
45 client
46 .put_object()
47 .set_write_offset_bytes(Some(offset))
48 .checksum_algorithm(ChecksumAlgorithm::Crc64Nvme)
49 .bucket(bucket)
50 .key(key)
51 .body(ByteStream::from(content_to_append)) .send()
53 .await?;
54 Ok(total_len)
55 }
56}
57
58#[cfg(test)]
59mod tests {
60
61 use crate::config::tracing_s3_config::TracingS3Config;
62 use crate::config::types::{
63 Bucket, BufferSizeLimitKb, CronIntervalInMs, Endpoint, ObjectSizeLimitMb, Postfix, Prefix,
64 };
65 use crate::s3_helpers::S3Helpers;
66 use chrono::Utc;
67
68 #[tokio::test]
69 pub async fn append_to_file_test() {
70 let config = TracingS3Config::new(
71 None,
72 None,
73 None,
74 Bucket(None),
75 Prefix("prefix"),
76 Postfix("log"),
77 Endpoint(None),
78 ObjectSizeLimitMb::new(1).unwrap(),
79 CronIntervalInMs::new(1_000).unwrap(),
80 BufferSizeLimitKb::new(1).unwrap(),
81 )
82 .await
83 .unwrap();
84 for _ in 0..5 {
85 let _result = S3Helpers::append_to_file(
86 &config.aws_client,
87 &config.bucket,
88 "check-file-exists.log",
89 &format!("hello world {}\n", Utc::now()),
90 )
91 .await;
92 }
93 }
94}