-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: support metrics log stream #28
Conversation
@computed_field | ||
@property | ||
def aws_cloudwatch_metrics_log_group(self) -> str: | ||
return ( | ||
f"/aws/greengrass/edge/{self.region}/" | ||
f"{self.account_id}/{self.profile}-edge-otaclient-metrics" | ||
) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
new log group name for metrics
from queue import Queue | ||
from typing import Literal, TypedDict | ||
|
||
from typing_extensions import NotRequired, TypeAlias | ||
|
||
LogsQueue: TypeAlias = "Queue[tuple[str, LogMessage]]" | ||
LogsQueue: TypeAlias = "Queue[tuple[LogGroupType, str, LogMessage]]" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
change the data format of the queue.
@@ -76,10 +76,13 @@ def generate_random_msgs( | |||
) -> list[tuple[str, LogMessage]]: | |||
_res: list[tuple[str, LogMessage]] = [] | |||
for _ in range(msg_num): | |||
_ecu, *_ = random.sample(ecus_list, 1) | |||
_ecu_id, *_ = random.sample(ecus_list, 1) | |||
_log_group_type = random.choice(list(LogGroupType)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
test both log group type.
cce23c4
to
33972d8
Compare
33972d8
to
3e59bb5
Compare
Coverage Report
|
for log_group_name in log_group_names: | ||
try: | ||
client.create_log_group(logGroupName=log_group_name) | ||
logger.info(f"{log_group_name=} has been created") | ||
except exc_types.ResourceAlreadyExistsException as e: | ||
logger.debug( | ||
f"{log_group_name=} already existed, skip creating: {e.response}" | ||
) | ||
raise e.__cause__ from None | ||
logger.error(f"failed to create {log_group_name=}: {e!r}") | ||
raise | ||
except Exception as e: | ||
logger.error(f"failed to create {log_group_name=}: {e!r}") | ||
raise | ||
except ValueError as e: | ||
if e.__cause__ and isinstance( | ||
e.__cause__, awscrt.exceptions.AwsCrtError | ||
): | ||
logger.error( | ||
(f"failed to create mtls connection to remote: {e.__cause__}") | ||
) | ||
raise e.__cause__ from None | ||
logger.error(f"failed to create {log_group_name=}: {e!r}") | ||
raise | ||
except Exception as e: | ||
logger.error(f"failed to create {log_group_name=}: {e!r}") | ||
raise |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Create both AWS CloudWatch log groups for LOG and METRICS.
3e59bb5
to
9b1a809
Compare
@@ -86,7 +97,7 @@ async def _put_log( | |||
) | |||
# logger.debug(f"receive log from {ecu_id}: {_logging_msg}") | |||
try: | |||
self._queue.put_nowait((ecu_id, _logging_msg)) | |||
self._queue.put_nowait((_logging_group_type, ecu_id, _logging_msg)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
put group type to queue, then aws_iot_logger
thread will get and handle it.
_log_group_type, _ecu_id, _log_msg = self._queue.get_nowait() | ||
# always log type is LOG in HTTP | ||
assert _log_group_type == LogGroupType.LOG |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
verify log group for HTTP.
assert _log_group_type == convert_from_log_type_to_log_group_type( | ||
item.log_type | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
verify log group for gRPC.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you! Overall LGTM, only some minor comments related to variables' name of logging group.
self._session_config = session_config | ||
self._log_group_name = session_config.aws_cloudwatch_log_group | ||
self._metrics_group_name = session_config.aws_cloudwatch_metrics_log_group | ||
self._interval = interval |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
About the variable naming here, previously we only have one log_group, so log_group equals to otaclient_logs log_group.
But now we have two log_groups, it becomes kind of ambiguous, (otaclient_logs_)log_group
and (otaclient_)metrics_group
are both (aws_cloudwatch_)log_group
.
I suggest that we prefix a otaclient_logs
to the variable name related to (otaclient_logs_)log_group
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you, agree.
Long formalized clear name should be better than short unclear name, fixed in the latest commit.
@computed_field | ||
@property | ||
def aws_cloudwatch_metrics_log_group(self) -> str: | ||
return ( | ||
f"/aws/greengrass/edge/{self.region}/" | ||
f"{self.account_id}/{self.profile}-edge-otaclient-metrics" | ||
) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggests that also change the previous aws_cloudwatch_log_group
property name into aws_cloudwatch_otaclient_logs_log_group
as we have two log groups now.
And to make naming schema matching, we can also rename aws_cloudwatch_metris_log_group
into aws_cloudwatch_otaclient_metrics_log_group
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you, fixed.
except Empty: | ||
break | ||
|
||
for log_stream_suffix, logs in message_dict.items(): | ||
for (log_group_type, log_stream_suffix), logs in message_dict.items(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice one, I just know that we can directly unpack tuple here!
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you!
By the way, is the AWS configured to have metrics_groups created or to allow otaclient creates the metrics_group?
UPDATED: seems the case is AWS is configured to allow greengrass web.auto agent create log_group with any names. Since iot-logger also uses greengrass cert, we can do log_group creation.
( Although I think it is not a good practice to do so, I think FMS should define log_groups with IaC in advance, instead of letting edge to do so 🤔
Let's consult with FMS team later about this topic 👍, seems like the current settings in IaC have been there for quite a long time, time to update it. |
Why
https://tier4.atlassian.net/browse/RT4-13461
This PR support a new log group for metrics on CloudWatch(
{self.profile}-edge-otaclient-metrics
).The reason why we switch the log group for metrics is that AWS subscription filter apply its filter based on the target log group level. Thus, by separating as log group, cloudwatch can apply the filter efficiently.
What
Change the existing data format in the queue and add
LogGroupType
field.Queue[tuple[ecu_id, LogMessage]]
Queue[tuple[LogGroupType(enum), ecu_id, LogMessage]]
Once logging thread receives the log group type from the queue, handle the target CloudWatch log group based on the incoming parameter. The new log group and stream name will be
/aws/greengrass/edge/{self.region}/{self.account_id}/{self.profile}-edge-otaclient
(same as the existing)yyyy/MM/dd/fms-${stage}-edge-${vehicle_id}-Core}/${ecu_id}
(same as the existing)/aws/greengrass/edge/{self.region}/{self.account_id}/{self.profile}-edge-otaclient-metrics
same as the existing log stream name
NOTE: Metrics is supported only in gRPC interface. In the existing HTTP interface, there is no way to use metrics.
Test