I have this elixir code using ExAws to fetch metrics from Cloudwatch.
defp fetch_and_save_metrics do
end_time = DateTime.utc_now()
start_time = DateTime.add(end_time, -5 * 60, :second)
opts = [
{:statistics, ["Maximum"]},
{:dimensions, [{"InstanceId", @instance_id}]}
]
case ExAws.Cloudwatch.get_metric_statistics(
"AWS/EC2",
"CPUUtilization",
start_time,
end_time,
300,
opts
)
|> ExAws.request() do
{:ok, metric_data} ->
IO.inspect(metric_data, label: "Raw CloudWatch Response", pretty: true)
{:error, error} ->
IO.inspect(error, label: "Raw CloudWatch Response", pretty: true)
When I run this code with a @instance_id that isn't running, it logs a response that tells me it's made a successful request, even though there isn't any data
Raw CloudWatch Response: %{
body: %{
label: "CPUUtilization",
request_id: <some uuid>,
metric_statistics: []
},
However, if I try to use a @instance_id that is running, I get the error
00:09:40.944 [error] GenServer #PID<0.200.0> terminating
** (MatchError) no match of right hand side value: :error
(sweet_xml 0.7.5) lib/sweet_xml.ex:873: SweetXml.to_cast/3
(sweet_xml 0.7.5) lib/sweet_xml.ex:630: SweetXml.xpath/3
(sweet_xml 0.7.5) lib/sweet_xml.ex:737: anonymous fn/3 in SweetXml.xmap/3
(elixir 1.18.1) lib/map.ex:957: Map.get_and_update/3
(sweet_xml 0.7.5) lib/sweet_xml.ex:737: SweetXml.xmap/3
(sweet_xml 0.7.5) lib/sweet_xml.ex:736: SweetXml.xmap/3
(elixir 1.18.1) lib/enum.ex:1714: Enum."-map/2-lists^map/1-1-"/2
(sweet_xml 0.7.5) lib/sweet_xml.ex:732: anonymous fn/4 in SweetXml.xmap/3
Last message: :fetch_metrics
State: %{}
I think I am handling the response from ExAws.request() just fine and if I remove any of my logic handling the response, I get the same error. I'm also able to successfully get the info I want using the same info I'm passing here using the AWS CLI. Given this and that the stack trace in the error doesn't include my code, is there something wrong with one of the dependencies I'm using, probably sweet_xml? Or is there some way I can fix my code. My dependencies are
defp deps do
[
{:ex_aws, "~> 2.4"},
{:ex_aws_cloudwatch, "~> 2.0"},
{:configparser_ex, "~> 4.0"},
{:hackney, "~> 1.18"},
{:jason, "~> 1.4"},
{:sweet_xml, "~> 0.7.5"}
]
end
Here is the exact line failing as you were told by the stack trace. It reads
{float,_} = Float.parse(to_string(value))
That said, somewhere in stats you have a value which is expected to be float()
but it is not. It’s impossible to guide you further at this point, but you surely might want to add some logging to the handler of :fetch_metrics
message and figure it out.