Packages
erlcloud
3.5.4
3.8.3
3.8.2
3.8.1
3.7.6
3.7.4
3.7.3
3.7.2
3.7.1
3.7.0
3.6.8
3.6.7
3.6.5
3.6.4
3.6.3
3.6.2
3.6.1
3.6.0
3.5.16
3.5.15
3.5.14
3.5.13
3.5.12
3.5.11
3.5.10
3.5.9
3.5.8
3.5.7
3.5.6
3.5.5
3.5.4
3.5.3
3.5.2
3.5.1
3.5.0
3.4.5
3.4.3
3.4.1
3.4.0
3.3.9
3.3.8
3.3.7
3.3.6
3.3.5
3.3.4
3.3.3
3.3.2
3.3.1
3.3.0
3.2.18
3.2.17
3.2.16
3.2.15
3.2.14
3.2.13
3.2.12
3.2.11
3.2.10
3.2.7
3.2.6
3.2.5
3.2.4
3.2.3
3.2.2
3.2.1
3.2.0
3.1.17
3.1.16
3.1.14
3.1.13
3.1.12
3.1.11
3.1.9
3.1.8
3.1.7
3.1.6
3.1.5
3.1.4
3.1.3
3.1.2
3.1.1
3.1.0
3.0.5
3.0.4
3.0.3
3.0.2
3.0.1
2.2.16
2.2.15
2.2.14
2.2.13
2.2.12
2.2.11
2.2.10
2.2.9
2.2.8
2.2.7
2.2.6
2.2.5
2.2.4
2.2.2
2.2.1
2.2.0
2.1.0
2.0.5
2.0.4
2.0.3
2.0.0
0.13.10
0.13.9
0.13.8
0.13.6
0.13.5
0.13.4
0.13.3
0.13.2
0.13.0
0.12.0
0.11.0
0.9.2
0.9.2-rc.1
0.9.1
0.9.0
AWS APIs library for Erlang
Current section
Files
Jump to
Current section
Files
src/erlcloud_cloudwatch_logs.erl
-module(erlcloud_cloudwatch_logs).
-include("erlcloud_aws.hrl").
-define(API_VERSION, "2014-03-28").
-define(API_PREFIX, "Logs_20140328").
-define(SERVICE_NAME, "logs").
-define(DEFAULT_LIMIT, 50).
-define(DEFAULT_HEADERS, [
{"content-type", "application/x-amz-json-1.1"},
{"accept", "application/json"}
]).
-type access_key_id() :: string().
-type secret_access_key() :: string().
-type cw_host() :: string().
-type paging_token() :: string() | binary() | undefined.
-type seq_token() :: string() | binary() | undefined.
-type log_group_name() :: string() | binary() | undefined.
-type log_group_name_prefix() :: string() | binary() | undefined.
-type log_stream_name() :: string() | binary() | undefined.
-type log_stream_prefix() :: string() | binary() | undefined.
-type limit() :: pos_integer() | undefined.
-type filter_name_prefix() :: string() | binary() | undefined.
-type metric_name() :: string() | binary() | undefined.
-type metric_namespace() :: string() | binary() | undefined.
-type log_stream_order() :: log_stream_name | last_event_time | undefined.
-type events() :: [#{message => binary(), timestamp => pos_integer()}].
-export_type([events/0]).
-type kms_key_id() :: string() | binary() | undefined.
-type success_result_paged(ObjectType) :: {ok, [ObjectType], paging_token()}.
-type error_result() :: {error, Reason :: term()}.
-type result_paged(ObjectType) :: success_result_paged(ObjectType) | error_result().
-type log_group() :: jsx:json_term().
-type log_stream() :: jsx:json_term().
-type metric_filters() :: jsx:json_term().
-type tag():: {binary(), binary()}.
-type tags_return() :: {error, metadata_not_available
| container_credentials_unavailable
| erlcloud_aws:httpc_result_error()}
| {ok, jsx:json_term()}.
-type query_status() :: cancelled
| complete
| failed
| running
| scheduled
| timeout
| unknown.
-export_type([query_status/0]).
-type query_results() :: #{ results := [[#{ field := binary(),
value := binary() }]],
statistics := #{ bytes_scanned := float(),
records_matched := float(),
records_scanned := float() },
status := query_status() }.
-export_type([query_results/0]).
%% Library initialization
-export([
configure/2,
configure/3,
new/2,
new/3
]).
%% CloudWatch API
-export([
create_log_group/1,
create_log_group/2,
create_log_group/3,
create_log_group/4,
create_log_stream/2,
create_log_stream/3,
delete_log_group/1,
delete_log_group/2,
delete_log_stream/2,
delete_log_stream/3,
describe_log_groups/0,
describe_log_groups/1,
describe_log_groups/2,
describe_log_groups/3,
describe_log_groups/4,
describe_log_streams/1,
describe_log_streams/2,
describe_log_streams/3,
describe_log_streams/5,
describe_log_streams/6,
describe_log_streams/7,
describe_metric_filters/0,
describe_metric_filters/1,
describe_metric_filters/2,
describe_metric_filters/3,
describe_metric_filters/4,
describe_metric_filters/6,
describe_metric_filters/7,
get_query_results/2,
get_query_results/3,
put_logs_events/4,
put_logs_events/5,
list_tags_log_group/1,
list_tags_log_group/2,
start_query/4,
start_query/5,
start_query/6,
stop_query/1,
stop_query/2,
tag_log_group/2,
tag_log_group/3
]).
%%==============================================================================
%% Library initialization
%%==============================================================================
-spec configure(access_key_id(), secret_access_key()) -> ok.
configure(AccessKeyID, SecretAccessKey) ->
put(aws_config, new(AccessKeyID, SecretAccessKey)),
ok.
-spec configure(access_key_id(), secret_access_key(), cw_host()) -> ok.
configure(AccessKeyID, SecretAccessKey, Host) ->
put(aws_config, new(AccessKeyID, SecretAccessKey, Host)),
ok.
-spec new(access_key_id(), secret_access_key()) -> aws_config().
new(AccessKeyID, SecretAccessKey) ->
#aws_config{
access_key_id = AccessKeyID,
secret_access_key = SecretAccessKey
}.
-spec new(access_key_id(), secret_access_key(), cw_host()) -> aws_config().
new(AccessKeyID, SecretAccessKey, Host) ->
#aws_config{
access_key_id = AccessKeyID,
secret_access_key = SecretAccessKey,
cloudwatch_logs_host = Host
}.
%%==============================================================================
%% CloudWatch API
%%==============================================================================
%%------------------------------------------------------------------------------
%% @doc
%%
%% CreateLogGroup action
%% http://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_CreateLogGroup.html
%%
%% @end
%%------------------------------------------------------------------------------
-spec create_log_group(log_group_name()) -> ok | error_result().
create_log_group(LogGroupName) ->
create_log_group(LogGroupName, default_config()).
-spec create_log_group(
log_group_name(),
aws_config()
) -> ok | error_result().
create_log_group(LogGroupName, Config) ->
create_log_group(LogGroupName, undefined, undefined, Config).
-spec create_log_group(
log_group_name(),
list(tag()),
aws_config()
) -> ok | error_result().
create_log_group(LogGroupName, Tags, Config) when is_list(Tags) ->
create_log_group(LogGroupName, Tags, undefined, Config).
-spec create_log_group(
log_group_name(),
undefined | list(tag()),
undefined | kms_key_id(),
aws_config()
) -> ok | error_result().
create_log_group(LogGroupName, Tags, KmsKeyId, Config) ->
case cw_request(Config, "CreateLogGroup", [
{<<"logGroupName">>, LogGroupName},
{<<"tags">>, Tags},
{<<"kmsKeyId">>, KmsKeyId}
])
of
{ok, []} -> ok;
{error, _} = Error -> Error
end.
%%------------------------------------------------------------------------------
%% @doc
%%
%% CreateLogStream action
%% http://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_CreateLogStream.html
%%
%% @end
%%------------------------------------------------------------------------------
-spec create_log_stream(
log_group_name(),
log_stream_name()
) -> ok | error_result().
create_log_stream(LogGroupName, LogStreamName) ->
create_log_stream(LogGroupName, LogStreamName, default_config()).
-spec create_log_stream(
log_group_name(),
log_stream_name(),
aws_config()
) -> ok | error_result().
create_log_stream(LogGroupName, LogStreamName, Config) ->
case cw_request(Config, "CreateLogStream", [
{<<"logGroupName">>, LogGroupName},
{<<"logStreamName">>, LogStreamName}
])
of
{ok, []} -> ok;
{error, _} = Error -> Error
end.
%%------------------------------------------------------------------------------
%% @doc
%%
%% DeleteLogGroup action
%% http://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_DeleteLogGroup.html
%%
%% @end
%%------------------------------------------------------------------------------
-spec delete_log_group(log_group_name()) -> ok | error_result().
delete_log_group(LogGroupName) ->
delete_log_group(LogGroupName, default_config()).
-spec delete_log_group(
log_group_name(),
aws_config()
) -> ok | error_result().
delete_log_group(LogGroupName, Config) ->
case cw_request(Config, "DeleteLogGroup", [
{<<"logGroupName">>, LogGroupName}
])
of
{ok, []} -> ok;
{error, _} = Error -> Error
end.
%%------------------------------------------------------------------------------
%% @doc
%%
%% DeleteLogStream action
%% http://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_DeleteLogStream.html
%%
%% @end
%%------------------------------------------------------------------------------
-spec delete_log_stream(
log_group_name(),
log_stream_name()
) -> ok | error_result().
delete_log_stream(LogGroupName, LogStreamName) ->
delete_log_stream(LogGroupName, LogStreamName, default_config()).
-spec delete_log_stream(
log_group_name(),
log_stream_name(),
aws_config()
) -> ok | error_result().
delete_log_stream(LogGroupName, LogStreamName, Config) ->
case cw_request(Config, "DeleteLogStream", [
{<<"logGroupName">>, LogGroupName},
{<<"logStreamName">>, LogStreamName}
])
of
{ok, []} -> ok;
{error, _} = Error -> Error
end.
%%------------------------------------------------------------------------------
%% @doc
%%
%% DescribeLogGroups action
%% http://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_DescribeLogGroups.html
%%
%% @end
%%------------------------------------------------------------------------------
-spec describe_log_groups() -> result_paged(log_group()).
describe_log_groups() ->
describe_log_groups(default_config()).
-spec describe_log_groups(
aws_config() | log_group_name_prefix()
) -> result_paged(log_group()).
describe_log_groups(#aws_config{} = Config) ->
describe_log_groups(undefined, Config);
describe_log_groups(LogGroupNamePrefix) ->
describe_log_groups(LogGroupNamePrefix, default_config()).
-spec describe_log_groups(
log_group_name_prefix(),
aws_config()
) -> result_paged(log_group()).
describe_log_groups(LogGroupNamePrefix, Config) ->
describe_log_groups(LogGroupNamePrefix, ?DEFAULT_LIMIT, Config).
-spec describe_log_groups(
log_group_name_prefix(),
limit(),
aws_config()
) -> result_paged(log_group()).
describe_log_groups(LogGroupNamePrefix, Limit, Config) ->
describe_log_groups(LogGroupNamePrefix, Limit, undefined, Config).
-spec describe_log_groups(
log_group_name_prefix(),
limit(),
paging_token(),
aws_config()
) -> result_paged(log_group()).
describe_log_groups(LogGroupNamePrefix, Limit, Token, Config) ->
case
cw_request(Config, "DescribeLogGroups",
req_log_groups(LogGroupNamePrefix, Limit, Token)
)
of
{ok, Json} ->
LogGroups = proplists:get_value(<<"logGroups">>, Json, []),
NextToken = proplists:get_value(<<"nextToken">>, Json, undefined),
{ok, LogGroups, NextToken};
{error, _} = Error ->
Error
end.
req_log_groups(LogGroupNamePrefix, Limit, Token) ->
[
{<<"limit">>, Limit},
{<<"logGroupNamePrefix">>, LogGroupNamePrefix},
{<<"nextToken">>, Token}
].
%%------------------------------------------------------------------------------
%% @doc
%%
%% DescribeLogStreams action
%% https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_DescribeLogStreams.html
%%
%% @end
%%------------------------------------------------------------------------------
-spec describe_log_streams(log_group_name()) -> result_paged(log_stream()).
describe_log_streams(LogGroupName) ->
describe_log_streams(LogGroupName, default_config()).
-spec describe_log_streams(
log_group_name(),
aws_config()
) -> result_paged(log_stream()).
describe_log_streams(LogGroupName, Config) ->
describe_log_streams(LogGroupName, undefined, Config).
-spec describe_log_streams(
log_group_name(),
log_stream_prefix(),
aws_config()
) -> result_paged(log_stream()).
describe_log_streams(LogGroupName, LogStreamPrefix, Config) ->
describe_log_streams(LogGroupName, LogStreamPrefix, log_stream_name, false, Config).
-spec describe_log_streams(
log_group_name(),
log_stream_prefix(),
log_stream_order(),
boolean(),
aws_config()
) -> result_paged(log_stream()).
describe_log_streams(LogGroupName, LogStreamPrefix, OrderBy, Desc, Config) ->
describe_log_streams(LogGroupName, LogStreamPrefix, OrderBy, Desc, ?DEFAULT_LIMIT, Config).
-spec describe_log_streams(
log_group_name(),
log_stream_prefix(),
log_stream_order(),
boolean(),
limit(),
aws_config()
) -> result_paged(log_stream()).
describe_log_streams(LogGroupName, LogStreamPrefix, OrderBy, Desc, Limit, Config) ->
describe_log_streams(LogGroupName, LogStreamPrefix, OrderBy, Desc, Limit, undefined, Config).
-spec describe_log_streams(
log_group_name(),
log_stream_prefix(),
log_stream_order(),
boolean(),
limit(),
paging_token(),
aws_config()
) -> result_paged(log_stream()).
describe_log_streams(LogGroupName, LogStreamPrefix, OrderBy, Desc, Limit, Token, Config) ->
case
cw_request(Config, "DescribeLogStreams",
req_log_streams(LogGroupName, LogStreamPrefix, OrderBy, Desc, Limit, Token)
)
of
{ok, Json} ->
LogStream = proplists:get_value(<<"logStreams">>, Json, []),
NextToken = proplists:get_value(<<"nextToken">>, Json, undefined),
{ok, LogStream, NextToken};
{error, _} = Error ->
Error
end.
req_log_streams(LogGroupName, LogStreamPrefix, OrderBy, Desc, Limit, Token) ->
[
{<<"descending">>, Desc},
{<<"limit">>, Limit},
{<<"logGroupName">>, LogGroupName},
{<<"logStreamNamePrefix">>, LogStreamPrefix},
{<<"nextToken">>, Token},
{<<"orderBy">>, log_stream_order_by(OrderBy)}
].
log_stream_order_by(undefined) -> <<"LogStreamName">>;
log_stream_order_by(log_stream_name) -> <<"LogStreamName">>;
log_stream_order_by(last_event_time) -> <<"LastEventTime">>.
%%------------------------------------------------------------------------------
%% @doc
%%
%% GetQueryResults action
%% https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_GetQueryResults.html
%%
%% ===Example===
%%
%% Returns the results from the specified query.
%%
%% `
%% application:ensure_all_started(erlcloud).
%% {ok, Config} = erlcloud_aws:auto_config().
%% {ok, Results} = erlcloud_cloudwatch_logs:get_query_results("12ab3456-12ab-123a-789e-1234567890ab", [], Config).
%% `
%%
%% @end
%%------------------------------------------------------------------------------
-spec get_query_results(QueryId, Options) -> Results
when QueryId :: string(),
Options :: [{out, map}],
Results :: {ok, query_results() | AWSAPIReturn} | {error, erlcloud_aws:httpc_result_error()},
AWSAPIReturn :: [{binary(), term()}]. % as per #API_GetQueryResults_ResponseSyntax
get_query_results(QueryId, Options) ->
get_query_results(QueryId, Options, default_config()).
-spec get_query_results(QueryId, Options, Config) -> Results
when QueryId :: string(),
Options :: [{out, map}],
Config :: aws_config(),
Results :: {ok, query_results() | AWSAPIReturn} | {error, erlcloud_aws:httpc_result_error()},
AWSAPIReturn :: [{binary(), term()}]. % as per #API_GetQueryResults_ResponseSyntax
get_query_results(QueryId, Options, Config) ->
Result0 = cw_request(Config, "GetQueryResults", [{<<"queryId">>, QueryId}]),
Out = proplists:get_value(out, Options, undefined),
case Result0 of
{error, _} = E -> E;
{ok, Result} when Out =:= map ->
Statistics = proplists:get_value(<<"statistics">>, Result),
{ok, #{ results => results_from_get_query_results(proplists:get_value(<<"results">>, Result)),
statistics => #{ bytes_scanned => proplists:get_value(<<"bytesScanned">>, Statistics),
records_matched => proplists:get_value(<<"recordsMatched">>, Statistics),
records_scanned => proplists:get_value(<<"recordsScanned">>, Statistics)
},
status => status_from_get_query_results(proplists:get_value(<<"status">>, Result)) }};
_ ->
Result0
end.
-spec results_from_get_query_results(ResultRows) -> Out
when ResultRows :: [[[{binary(), binary()}]]],
Out :: [[#{ field := binary(),
value := binary() }]].
results_from_get_query_results([]) ->
[];
results_from_get_query_results(ResultRows) ->
[ [#{ field => proplists:get_value(<<"field">>, ResultField),
value => proplists:get_value(<<"value">>, ResultField) }
|| ResultField <- ResultRow ]
|| ResultRow <- ResultRows ].
-spec status_from_get_query_results(In) -> Out
when In :: binary(),
Out :: query_status().
status_from_get_query_results(<<"Cancelled">>) ->
cancelled;
status_from_get_query_results(<<"Complete">>) ->
complete;
status_from_get_query_results(<<"Failed">>) ->
failed;
status_from_get_query_results(<<"Running">>) ->
running;
status_from_get_query_results(<<"Scheduled">>) ->
scheduled;
status_from_get_query_results(<<"Timeout">>) ->
timeout;
status_from_get_query_results(<<"Unknown">>) ->
unknown.
%%------------------------------------------------------------------------------
%% @doc
%%
%% PutLogEvents action
%% https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_PutLogEvents.html
%%
%% ===Example===
%%
%% Put log events requires a Upload Sequence Token, it is available via DescribeLogStreams
%%
%% `
%% application:ensure_all_started(erlcloud).
%% {ok, Config} = erlcloud_aws:auto_config().
%% {ok, Streams, _} = erlcloud_cloudwatch_logs:describe_log_streams(GroupName, StreamName, Config).
%% {_, Seq} = lists:keyfind(<<"uploadSequenceToken">>, 1, hd(Streams)).
%%
%% Batch = [#{timestamp => 1526233086694, message => <<"Example Message">>}].
%% erlcloud_cloudwatch_logs:put_logs_events(GroupName, StreamName, Seq, Batch, Config).
%% `
%%
%% @end
%%------------------------------------------------------------------------------
-spec put_logs_events(
log_group_name(),
log_stream_name(),
seq_token(),
events()
) -> {ok, seq_token()} | {error, erlcloud_aws:httpc_result_error()}.
put_logs_events(LogGroup, LogStream, SeqToken, Events) ->
put_logs_events(LogGroup, LogStream, SeqToken, Events, default_config()).
-spec put_logs_events(
log_group_name(),
log_stream_name(),
seq_token(),
events(),
aws_config()
) -> {ok, seq_token()} | {error, erlcloud_aws:httpc_result_error()}.
put_logs_events(LogGroup, LogStream, SeqToken, Events, Config) ->
case
cw_request(Config, "PutLogEvents",
req_logs_events(LogGroup, LogStream, SeqToken, Events)
)
of
{ok, Json} ->
Seq = proplists:get_value(<<"nextSequenceToken">>, Json, []),
{ok, Seq};
{error, _} = Error ->
Error
end.
req_logs_events(LogGroup, LogStream, SeqToken, Events) ->
[
{<<"logEvents">>, log_events(Events)},
{<<"logGroupName">>, LogGroup},
{<<"logStreamName">>, LogStream},
{<<"sequenceToken">>, SeqToken}
].
log_events(Events) ->
[maps:with([message, timestamp], X) ||
#{message := _, timestamp := _} = X <- Events].
%%------------------------------------------------------------------------------
%% @doc
%%
%% DescribeMetricFilters action
%% https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_DescribeMetricFilters.html
%%
%% @end
%%------------------------------------------------------------------------------
-spec describe_metric_filters() -> result_paged(metric_filters()).
describe_metric_filters() ->
describe_metric_filters(default_config()).
-spec describe_metric_filters(
aws_config() | log_group_name()
) -> result_paged(metric_filters()).
describe_metric_filters(#aws_config{} = Config) ->
describe_metric_filters(undefined, Config);
describe_metric_filters(LogGroupName) ->
describe_metric_filters(LogGroupName, default_config()).
-spec describe_metric_filters(
log_group_name(),
aws_config()
) -> result_paged(metric_filters()).
describe_metric_filters(LogGroupName, Config) ->
describe_metric_filters(LogGroupName, ?DEFAULT_LIMIT, Config).
-spec describe_metric_filters(
log_group_name(),
limit(),
aws_config()
) -> result_paged(metric_filters()).
describe_metric_filters(LogGroupName, Limit, Config) ->
describe_metric_filters(LogGroupName, Limit, undefined, Config).
-spec describe_metric_filters(
log_group_name(),
limit(),
filter_name_prefix(),
aws_config()
) -> result_paged(metric_filters()).
describe_metric_filters(LogGroupName, Limit, FilterNamePrefix, Config) ->
describe_metric_filters(LogGroupName, Limit, FilterNamePrefix, undefined,
undefined, Config).
-spec describe_metric_filters(
log_group_name(),
limit(),
filter_name_prefix(),
metric_name(),
metric_namespace(),
aws_config()
) -> result_paged(metric_filters()).
describe_metric_filters(LogGroupName, Limit, FilterNamePrefix, MetricName,
MetricNamespace, Config) ->
describe_metric_filters(LogGroupName, Limit, FilterNamePrefix, MetricName,
MetricNamespace, undefined, Config).
-spec describe_metric_filters(
log_group_name(),
limit(),
filter_name_prefix(),
metric_name(),
metric_namespace(),
paging_token(),
aws_config()
) -> result_paged(metric_filters()).
describe_metric_filters(LogGroupName, Limit, FilterNamePrefix, MetricName,
MetricNamespace, PrevToken, Config) ->
case cw_request(Config, "DescribeMetricFilters", [
{<<"logGroupName">>, LogGroupName},
{<<"limit">>, Limit},
{<<"filterNamePrefix">>, FilterNamePrefix},
{<<"metricName">>, MetricName},
{<<"metricNamespace">>, MetricNamespace},
{<<"nextToken">>, PrevToken}
]) of
{ok, Data} ->
MetricFilters = proplists:get_value(<<"metricFilters">>, Data, []),
NextToken = proplists:get_value(<<"nextToken">>, Data, undefined),
{ok, MetricFilters, NextToken};
{error, Reason} ->
{error, Reason}
end.
%%------------------------------------------------------------------------------
%% @doc
%%
%% ListTagsLogGroup
%% https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_ListTagsLogGroup.html
%%
%% @end
%%------------------------------------------------------------------------------
-spec list_tags_log_group(
log_group_name()
) -> tags_return().
list_tags_log_group(LogGroup) ->
list_tags_log_group(LogGroup, default_config()).
-spec list_tags_log_group(
log_group_name(),
aws_config()
) -> tags_return().
list_tags_log_group(LogGroup, Config) ->
case
cw_request(Config, "ListTagsLogGroup", [{<<"logGroupName">>, LogGroup}])
of
{ok, Json} ->
Tags = proplists:get_value(<<"tags">>, Json, []),
{ok, Tags};
{error, _} = Error ->
Error
end.
%%------------------------------------------------------------------------------
%% @doc
%%
%% StartQuery action
%% https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_StartQuery.html
%%
%% ===Example===
%%
%% Schedules a query of log groups using CloudWatch Logs Insights. You specify the log groups
%% and time range to query, as well as the query string to use.
%%
%% `
%% {ok, _} = application:ensure_all_started(erlcloud).
%% {ok, Config} = erlcloud_aws:auto_config().
%% {ok, #{ query_id := QueryId }} = erlcloud_cloudwatch_logs:start_query(["LogGroupName1", "LogGroupName2", "LogGroupName3"], "stats count(*) by eventSource, eventName, awsRegion", 1546300800, 1546309800, 100).
%% `
%%
%% @end
%%------------------------------------------------------------------------------
-spec start_query(LogGroupNames, QueryString, StartTime, EndTime) -> Result
when LogGroupNames :: [log_group_name()],
QueryString :: string(),
StartTime :: non_neg_integer(),
EndTime :: non_neg_integer(),
Result :: {ok, #{ query_id => string() }} | {error, erlcloud_aws:httpc_result_error()}.
start_query(LogGroupNames0, QueryString, StartTime, EndTime) ->
start_query(LogGroupNames0, QueryString, StartTime, EndTime, _Limit = 1000).
-spec start_query(LogGroupNames, QueryString, StartTime, EndTime, Limit) -> Result
when LogGroupNames :: [log_group_name()],
QueryString :: string(),
StartTime :: non_neg_integer(),
EndTime :: non_neg_integer(),
Limit :: 1..10000,
Result :: {ok, #{ query_id => string() }} | {error, erlcloud_aws:httpc_result_error()}.
start_query(LogGroupNames0, QueryString, StartTime, EndTime, Limit) ->
start_query(LogGroupNames0, QueryString, StartTime, EndTime, Limit, default_config()).
-spec start_query(LogGroupNames, QueryString, StartTime, EndTime, Limit, Config) -> Result
when LogGroupNames :: [log_group_name()],
QueryString :: string(),
StartTime :: non_neg_integer(),
EndTime :: non_neg_integer(),
Limit :: 1..10000,
Config :: aws_config(),
Result :: {ok, #{ query_id => string() }} | {error, erlcloud_aws:httpc_result_error()}.
start_query(LogGroupNames0, QueryString, StartTime, EndTime, Limit, Config) ->
LogGroupNames = case LogGroupNames0 of
[LogGroupName] ->
[{<<"logGroupName">>, LogGroupName}];
_ ->
[{<<"logGroupNames">>, LogGroupNames0}]
end,
Result = cw_request(Config, "StartQuery", LogGroupNames ++ [{<<"queryString">>, QueryString},
{<<"startTime">>, StartTime},
{<<"endTime">>, EndTime},
{<<"limit">>, Limit}]),
case Result of
{error, _} = E -> E;
{ok, OK} -> {ok, #{ query_id => binary_to_list(proplists:get_value(<<"queryId">>, OK)) }}
end.
%%------------------------------------------------------------------------------
%% @doc
%%
%% StopQuery action
%% https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_StopQuery.html
%%
%% ===Example===
%%
%% Stops a CloudWatch Logs Insights query that is in progress.
%%
%% `
%% {ok, _} = application:ensure_all_started(erlcloud).
%% {ok, Config} = erlcloud_aws:auto_config().
%% {ok, QueryId} = erlcloud_cloudwatch_logs:stop_query("ecef5848-8aa7-4c12-9665-bafe422f3247").
%% `
%%
%% @end
%%------------------------------------------------------------------------------
-spec stop_query(QueryId) -> Result
when QueryId :: string(),
Result :: ok | {error, erlcloud_aws:httpc_result_error()}.
stop_query(QueryId) ->
stop_query(QueryId, default_config()).
-spec stop_query(QueryId, Config) -> Result
when QueryId :: string(),
Config :: aws_config(),
Result :: ok | {error, erlcloud_aws:httpc_result_error()}.
stop_query(QueryId, Config) ->
Result = cw_request(Config, "StopQuery", [{<<"queryId">>, QueryId}]),
case Result of
{error, _} = E -> E;
{ok, _} -> ok
end.
%%------------------------------------------------------------------------------
%% @doc
%%
%% TagLogGroup action
%% https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_TagLogGroup.html
%%
%% @end
%%------------------------------------------------------------------------------
-spec tag_log_group(
log_group_name(),
list(tag())
) -> {ok, []}
| {ok, jsx:json_term()}
| {error, erlcloud_aws:httpc_result_error()}.
tag_log_group(LogGroup, Tags) when is_list(Tags) ->
tag_log_group(LogGroup, Tags, default_config()).
-spec tag_log_group(
log_group_name(),
list(tag()),
aws_config()
) -> {ok, []}
| {ok, jsx:json_term()}
| {error, erlcloud_aws:httpc_result_error()}.
tag_log_group(LogGroup, Tags, Config) when is_list(Tags) ->
Params = [{<<"logGroupName">>, LogGroup},
{<<"tags">>, Tags}
],
cw_request(Config, "TagLogGroup", Params).
%%==============================================================================
%% Internal functions
%%==============================================================================
default_config() ->
erlcloud_aws:default_config().
cw_request(Config, Action, Params) ->
maybe_cw_request(erlcloud_aws:update_config(Config), Action, Params).
maybe_cw_request({ok, Config}, Action, Params) ->
Request = make_request_body(Action, Params),
maybe_json(
erlcloud_aws:aws_request_form_raw(
post,
Config#aws_config.cloudwatch_logs_scheme,
Config#aws_config.cloudwatch_logs_host,
Config#aws_config.cloudwatch_logs_port,
"/",
Request,
make_request_headers(Config, Action, Request),
[],
Config
)
);
maybe_cw_request({error, _} = Error, _Action, _Params) ->
Error.
maybe_json({ok, <<>>}) ->
{ok, []};
maybe_json({ok, Response}) ->
{ok, jsx:decode(Response, [{return_maps, false}])};
maybe_json({error, _} = Error) ->
Error.
make_request_headers(Config, Action, Body) ->
lists:append(make_signed_headers(Config, Action, Body), ?DEFAULT_HEADERS).
make_signed_headers(Config, Action, Body) ->
#aws_config{cloudwatch_logs_host = Host} = Config,
Target = lists:append([?API_PREFIX, ".", Action]),
Headers = [{"host", Host}, {"x-amz-target", Target}],
Region = erlcloud_aws:aws_region_from_host(Host),
erlcloud_aws:sign_v4_headers(Config, Headers, Body, Region, ?SERVICE_NAME).
make_request_body(Action, RequestParams) ->
DefaultParams = [{<<"Action">>, Action}, {<<"Version">>, ?API_VERSION}],
Params = lists:append(DefaultParams, RequestParams),
jsx:encode(prepare_request_params(Params)).
prepare_request_params(Params) ->
lists:filtermap(fun prepare_request_param/1, Params).
prepare_request_param({_Key, undefined}) ->
false;
prepare_request_param({Key, [H | _] = Value})
when is_integer(H) ->
{true, {Key, list_to_binary(Value)}};
prepare_request_param({Key, Value}) ->
{true, {Key, Value}}.