@@ -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