Skip to content

Commit 8052f26

Browse files
committed
feat: Create log stream if it doesn't exist
1 parent d57d455 commit 8052f26

File tree

1 file changed

+61
-1
lines changed

1 file changed

+61
-1
lines changed

lib/cadet/logger/cloudwatch_logger.ex

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,14 +151,74 @@ defmodule Cadet.Logger.CloudWatchLogger do
151151

152152
defp send_to_cloudwatch(log_stream, log_group, buffer) do
153153
# Ensure that the already have ExAws authentication configured
154-
with :ok <- check_exaws_config() do
154+
with :ok <- check_exaws_config(),
155+
:ok <- ensure_log_stream_exists(log_group, log_stream) do
155156
operation = build_log_operation(log_stream, log_group, buffer)
156157

157158
operation
158159
|> send_with_retry()
159160
end
160161
end
161162

163+
# Ensures the log stream exists, creates it if not
164+
# Returns :ok or :error
165+
# Uses ExAws.Logs.describe_log_streams and ExAws.Logs.create_log_stream
166+
# Assumes ExAws.Logs is available
167+
168+
defp ensure_log_stream_exists(log_group, log_stream) do
169+
describe_op = %ExAws.Operation.JSON{
170+
http_method: :post,
171+
service: :logs,
172+
headers: [
173+
{"x-amz-target", "Logs_20140328.DescribeLogStreams"},
174+
{"content-type", "application/x-amz-json-1.1"}
175+
],
176+
data: %{
177+
"logGroupName" => log_group,
178+
"logStreamNamePrefix" => log_stream
179+
}
180+
}
181+
182+
client = Application.get_env(:ex_aws, :ex_aws_mock, ExAws)
183+
184+
case client.request(describe_op) do
185+
{:ok, %{"logStreams" => streams}} ->
186+
if Enum.any?(streams, fn s -> s["logStreamName"] == log_stream end) do
187+
:ok
188+
else
189+
create_log_stream(log_group, log_stream, client)
190+
end
191+
192+
{:error, reason} ->
193+
Logger.error("Failed to describe log streams: #{inspect(reason)}")
194+
:error
195+
end
196+
end
197+
198+
defp create_log_stream(log_group, log_stream, client) do
199+
create_op = %ExAws.Operation.JSON{
200+
http_method: :post,
201+
service: :logs,
202+
headers: [
203+
{"x-amz-target", "Logs_20140328.CreateLogStream"},
204+
{"content-type", "application/x-amz-json-1.1"}
205+
],
206+
data: %{
207+
"logGroupName" => log_group,
208+
"logStreamName" => log_stream
209+
}
210+
}
211+
212+
case client.request(create_op) do
213+
{:ok, _} ->
214+
:ok
215+
216+
{:error, reason} ->
217+
Logger.error("Failed to create log stream: #{inspect(reason)}")
218+
:error
219+
end
220+
end
221+
162222
defp build_log_operation(log_stream, log_group, buffer) do
163223
# The headers and body structure can be found in the AWS API documentation:
164224
# https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_PutLogEvents.html

0 commit comments

Comments
 (0)