-
Notifications
You must be signed in to change notification settings - Fork 160
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added metric reporting functions (#898)
Adds metric reporting functions that are platform specific that can be used in the Device Defender custom metrics Commit change log: * Added metric reporting functions that are platform specific that can be used in the Device Defender custom metrics * Fixed formatting issues and unused variable issues on Mac * Additional Mac fixes * Moved metrics reporting to system_info * Clang format fixes * Changed how CPU is reported so it is clearer, detects errors faster, and handles more situations * Clang format and clang tidy fixes * Fixed LGTM error and unused variable issue on Mac * Added use of aws_*_u64_checked and removed debug print statement * Clang format fix (I need to setup Clang-format on linux...) * Process count and memory usage now reports using int64_t * WIP initial CPU usage sampler * Adjusted CPU usage sampler to fit correct design * Clang format fixes * Further clang-format fixes - missed a couple minor issues * Code review changes - first half * Code review part 2 - refactored cpu_usage_sampler into OS specific folders. Added stub/default implementation for Windows and MacOS * Clang format fix * Further clang-format fixes * Code review changes: Moved generic API functions for reuse, simplified code, adjusted comments * Fixed clang format issues, fixed Windows compiling and clang-tidy * More clang-tidy fixes * Adjusted after code review: Added private header file for CPU sampler, changed linux to cache result on constructor, unsupported platforms return null * Fixed unused argument issue on Windows * Fix header guard using incorrect format
- Loading branch information
1 parent
7279561
commit 9b2a8b7
Showing
10 changed files
with
367 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
#ifndef AWS_COMMON_CPU_USAGE_SAMPLER_H | ||
#define AWS_COMMON_CPU_USAGE_SAMPLER_H | ||
|
||
/** | ||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
* SPDX-License-Identifier: Apache-2.0. | ||
*/ | ||
|
||
#include <aws/common/common.h> | ||
#include <aws/common/math.h> | ||
|
||
/** | ||
* A struct that contains the CPU sampler for this platform. | ||
* Currently only Linux is supported. | ||
* | ||
* Note: Must be freed from memory using aws_cpu_sampler_destroy when finished. | ||
*/ | ||
struct aws_cpu_sampler; | ||
|
||
AWS_EXTERN_C_BEGIN | ||
|
||
/** | ||
* Creates a new CPU sampler using the provided allocator, or will return NULL if there is an error. | ||
* | ||
* Note: On unsupported platforms, the CPU sampler returned will return AWS_OP_ERR when calling | ||
* aws_cpu_sampler_get_sample. You will still need to call aws_cpu_sampler_clean_up when finished | ||
* to free the memory even for unsupported platforms. | ||
*/ | ||
AWS_COMMON_API | ||
struct aws_cpu_sampler *aws_cpu_sampler_new(struct aws_allocator *allocator); | ||
|
||
/** | ||
* Frees the memory used by the CPU sampler. | ||
*/ | ||
AWS_COMMON_API | ||
void aws_cpu_sampler_destroy(struct aws_cpu_sampler *sampler); | ||
|
||
/** | ||
* Gets the CPU usage and populates the given double, output, with the value. The value | ||
* returned is a percentage from 0.0 to 100.0. | ||
* | ||
* Will return AWS_OP_SUCCESS if polling the CPU was successful. AWS_OP_ERR will be returned | ||
* if the result should not be used or if there was an error polling the CPU. | ||
* | ||
* Will always return AWS_OP_ERR for unsupported platforms. | ||
*/ | ||
AWS_COMMON_API | ||
int aws_cpu_sampler_get_sample(struct aws_cpu_sampler *sampler, double *output); | ||
|
||
AWS_EXTERN_C_END | ||
|
||
#endif /* AWS_COMMON_CPU_USAGE_SAMPLER_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
#ifndef AWS_COMMON_PRIVATE_CPU_USAGE_SAMPLER_PRIVATE_H | ||
#define AWS_COMMON_PRIVATE_CPU_USAGE_SAMPLER_PRIVATE_H | ||
|
||
/** | ||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
* SPDX-License-Identifier: Apache-2.0. | ||
*/ | ||
|
||
#include <aws/common/common.h> | ||
#include <aws/common/math.h> | ||
|
||
/** | ||
* The VTable for the CPU sampler in cpu_usage_sampler.h | ||
*/ | ||
struct aws_cpu_sampler_vtable { | ||
int (*aws_get_cpu_sample_fn)(struct aws_cpu_sampler *sampler, double *output); | ||
void (*aws_cpu_sampler_destroy)(struct aws_cpu_sampler *sampler); | ||
}; | ||
|
||
/** | ||
* The CPU sampler in cpu_usage_sampler.h | ||
*/ | ||
struct aws_cpu_sampler { | ||
const struct aws_cpu_sampler_vtable *vtable; | ||
struct aws_allocator *allocator; | ||
void *impl; | ||
}; | ||
|
||
#endif /* AWS_COMMON_PRIVATE_CPU_USAGE_SAMPLER_PRIVATE_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
/** | ||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
* SPDX-License-Identifier: Apache-2.0. | ||
*/ | ||
|
||
#include <aws/common/cpu_usage_sampler.h> | ||
#include <aws/common/private/cpu_usage_sampler_private.h> | ||
|
||
/********************************************************************************************************************* | ||
* Public operations | ||
********************************************************************************************************************/ | ||
|
||
void aws_cpu_sampler_destroy(struct aws_cpu_sampler *sampler) { | ||
if (sampler == NULL) { | ||
return; | ||
} | ||
if (sampler->vtable->aws_cpu_sampler_destroy == NULL) { | ||
return; | ||
} | ||
sampler->vtable->aws_cpu_sampler_destroy(sampler); | ||
} | ||
|
||
int aws_cpu_sampler_get_sample(struct aws_cpu_sampler *sampler, double *output) { | ||
if (sampler == NULL) { | ||
aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); | ||
return AWS_OP_ERR; | ||
} | ||
if (sampler->vtable->aws_get_cpu_sample_fn == NULL) { | ||
aws_raise_error(AWS_ERROR_PLATFORM_NOT_SUPPORTED); | ||
return AWS_OP_ERR; | ||
} | ||
return sampler->vtable->aws_get_cpu_sample_fn(sampler, output); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
/** | ||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
* SPDX-License-Identifier: Apache-2.0. | ||
*/ | ||
|
||
#include <aws/common/cpu_usage_sampler.h> | ||
#include <aws/common/private/cpu_usage_sampler_private.h> | ||
|
||
/********************************************************************************************************************* | ||
* Public operations | ||
********************************************************************************************************************/ | ||
|
||
struct aws_cpu_sampler *aws_cpu_sampler_new(struct aws_allocator *allocator) { | ||
// OS currently not supported | ||
(void)(allocator); | ||
aws_raise_error(AWS_ERROR_PLATFORM_NOT_SUPPORTED); | ||
return NULL; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
/** | ||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
* SPDX-License-Identifier: Apache-2.0. | ||
*/ | ||
|
||
#include <aws/common/cpu_usage_sampler.h> | ||
#include <aws/common/private/cpu_usage_sampler_private.h> | ||
|
||
#include <inttypes.h> | ||
#include <sys/sysinfo.h> | ||
#include <sys/types.h> | ||
|
||
/********************************************************************************************************************* | ||
* Linux Specific | ||
********************************************************************************************************************/ | ||
|
||
struct aws_cpu_sampler_linux { | ||
struct aws_cpu_sampler base; | ||
|
||
uint64_t cpu_last_total_user; | ||
uint64_t cpu_last_total_user_low; | ||
uint64_t cpu_last_total_system; | ||
uint64_t cpu_last_total_idle; | ||
}; | ||
|
||
static void s_get_cpu_usage_linux( | ||
uint64_t *total_user, | ||
uint64_t *total_user_low, | ||
uint64_t *total_system, | ||
uint64_t *total_idle) { | ||
|
||
FILE *file; | ||
int matched_results; | ||
file = fopen("/proc/stat", "r"); | ||
matched_results = fscanf( | ||
file, | ||
"cpu %" SCNu64 " %" SCNu64 " %" SCNu64 " %" SCNu64 "", | ||
(uint64_t *)total_user, | ||
(uint64_t *)total_user_low, | ||
(uint64_t *)total_system, | ||
(uint64_t *)total_idle); | ||
fclose(file); | ||
if (matched_results == EOF || matched_results != 4) { | ||
aws_raise_error(AWS_ERROR_INVALID_STATE); | ||
} | ||
} | ||
|
||
static void aws_get_cpu_sample_fn_linux_get_uint64_delta(uint64_t first, uint64_t second, uint64_t *output) { | ||
if (first > second) { | ||
aws_sub_u64_checked(first, second, output); | ||
} else { | ||
aws_add_u64_checked((UINT64_MAX - second), first, output); | ||
} | ||
} | ||
|
||
static int aws_get_cpu_sample_fn_linux(struct aws_cpu_sampler *sampler, double *output) { | ||
struct aws_cpu_sampler_linux *sampler_linux = sampler->impl; | ||
|
||
int return_result = AWS_OP_ERR; | ||
uint64_t total_user, total_user_low, total_system, total_idle, total; | ||
s_get_cpu_usage_linux(&total_user, &total_user_low, &total_system, &total_idle); | ||
// total_combined needs to be double to allow for fractions | ||
double percent, total_combined; | ||
|
||
uint64_t total_user_delta = 0, total_user_low_delta = 0, total_system_delta = 0, total_idle_delta = 0; | ||
aws_get_cpu_sample_fn_linux_get_uint64_delta(total_user, sampler_linux->cpu_last_total_user, &total_user_delta); | ||
aws_get_cpu_sample_fn_linux_get_uint64_delta( | ||
total_user_low, sampler_linux->cpu_last_total_user_low, &total_user_low_delta); | ||
aws_get_cpu_sample_fn_linux_get_uint64_delta( | ||
total_system, sampler_linux->cpu_last_total_system, &total_system_delta); | ||
aws_get_cpu_sample_fn_linux_get_uint64_delta(total_idle, sampler_linux->cpu_last_total_idle, &total_idle_delta); | ||
|
||
total_combined = (double)(total_user_delta) + (double)(total_user_low_delta) + (double)(total_system_delta); | ||
total = total_combined + (double)(total_idle_delta); | ||
|
||
if (total == 0) { | ||
*output = 0; | ||
return_result = AWS_OP_ERR; | ||
goto cleanup; | ||
} | ||
|
||
percent = (total_combined / total) * 100; | ||
|
||
// If negative, there was an error (overflow?) | ||
if (percent < 0) { | ||
*output = 0; | ||
return_result = AWS_OP_ERR; | ||
goto cleanup; | ||
} | ||
|
||
*output = percent; | ||
return_result = AWS_OP_SUCCESS; | ||
|
||
cleanup: | ||
// Cache results | ||
sampler_linux->cpu_last_total_user = total_user; | ||
sampler_linux->cpu_last_total_user_low = total_user_low; | ||
sampler_linux->cpu_last_total_system = total_system; | ||
sampler_linux->cpu_last_total_idle = total_idle; | ||
|
||
return return_result; | ||
} | ||
|
||
static void aws_cpu_sampler_destroy_linux(struct aws_cpu_sampler *sampler) { | ||
if (sampler == NULL) { | ||
return; | ||
} | ||
struct aws_cpu_sampler_linux *sampler_linux = (struct aws_cpu_sampler_linux *)sampler->impl; | ||
aws_mem_release(sampler->allocator, sampler_linux); | ||
} | ||
|
||
static struct aws_cpu_sampler_vtable aws_cpu_sampler_vtable_linux = { | ||
.aws_get_cpu_sample_fn = aws_get_cpu_sample_fn_linux, | ||
.aws_cpu_sampler_destroy = aws_cpu_sampler_destroy_linux, | ||
}; | ||
|
||
/********************************************************************************************************************* | ||
* Public operations | ||
********************************************************************************************************************/ | ||
|
||
struct aws_cpu_sampler *aws_cpu_sampler_new(struct aws_allocator *allocator) { | ||
if (allocator == NULL) { | ||
aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); | ||
return NULL; | ||
} | ||
|
||
struct aws_cpu_sampler_linux *output_linux = aws_mem_calloc(allocator, 1, sizeof(struct aws_cpu_sampler_linux)); | ||
if (output_linux == NULL) { | ||
return NULL; | ||
} | ||
output_linux->base.allocator = allocator; | ||
output_linux->base.vtable = &aws_cpu_sampler_vtable_linux; | ||
output_linux->base.impl = output_linux; | ||
|
||
// CPU reporting is done via deltas, so we need to cache the initial CPU values | ||
double tmp = 0; | ||
aws_get_cpu_sample_fn_linux(&output_linux->base, &tmp); | ||
|
||
return &output_linux->base; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
/** | ||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
* SPDX-License-Identifier: Apache-2.0. | ||
*/ | ||
|
||
#include <aws/common/cpu_usage_sampler.h> | ||
#include <aws/common/private/cpu_usage_sampler_private.h> | ||
|
||
/********************************************************************************************************************* | ||
* Public operations | ||
********************************************************************************************************************/ | ||
|
||
struct aws_cpu_sampler *aws_cpu_sampler_new(struct aws_allocator *allocator) { | ||
// OS currently not supported | ||
(void)(allocator); | ||
aws_raise_error(AWS_ERROR_PLATFORM_NOT_SUPPORTED); | ||
return NULL; | ||
} |
Oops, something went wrong.