├── .codecov.yml ├── .github ├── PULL_REQUEST_TEMPLATE.md ├── dependabot.yml └── workflows │ ├── autoapprove.yml │ ├── automerge.yml │ ├── build_and_test.yml │ ├── build_and_test_release_latest.yml │ └── release_latest.repos ├── .rosinstall.master ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── NOTICE ├── README.md └── health_metric_collector ├── CHANGELOG.rst ├── CMakeLists.txt ├── LICENSE.txt ├── NOTICE.txt ├── config └── sample_configuration.yaml ├── include └── health_metric_collector │ ├── collect_and_publish.h │ ├── cpu_data.h │ ├── cpu_metric_collector.h │ ├── cpu_stats.h │ ├── metric_collector.h │ ├── metric_manager.h │ └── sys_info_collector.h ├── launch ├── health_metric_collector.launch.py └── sample_application.launch.py ├── package.xml ├── src ├── collector.cpp ├── cpu_data.cpp ├── cpu_metric_collector.cpp ├── cpu_stats.cpp ├── metric_manager.cpp └── sys_info_collector.cpp └── test └── health_metric_collector_test.cpp /.codecov.yml: -------------------------------------------------------------------------------- 1 | coverage: 2 | ignore: 3 | - "**/test/*" 4 | status: 5 | # doc: https://docs.codecov.io/docs/commit-status 6 | project: 7 | default: 8 | # will use the coverage from the base commit (pull request base or parent commit) coverage to compare against. 9 | target: auto 10 | threshold: null 11 | # will use the pull request base if the commit is on a pull request. If not, the parent commit will be used. 12 | base: auto 13 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | *Issue #, if available:* 2 | 3 | *Description of changes:* 4 | 5 | 6 | By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. 7 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: github-actions 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | time: "16:00" 8 | open-pull-requests-limit: 10 9 | 10 | -------------------------------------------------------------------------------- /.github/workflows/autoapprove.yml: -------------------------------------------------------------------------------- 1 | name: Auto approve 2 | 3 | on: pull_request 4 | 5 | jobs: 6 | # Auto-approve dependabot PRs since this repo requires at least one approving review. 7 | # Dependabot will automatically merge minor version upgrades 8 | # (see .dependabot/config.yml for more info). 9 | auto-approve-dependabot: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: hmarr/auto-approve-action@v2.0.0 13 | if: github.actor == 'dependabot[bot]' || github.actor == 'dependabot-preview[bot]' 14 | with: 15 | github-token: "${{ secrets.GITHUB_TOKEN }}" -------------------------------------------------------------------------------- /.github/workflows/automerge.yml: -------------------------------------------------------------------------------- 1 | name: Auto merge 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | master 7 | pull_request_review: 8 | types: 9 | - submitted 10 | check_suite: 11 | types: 12 | - completed 13 | status: {} 14 | jobs: 15 | # Automatically merge approved and green dependabot PRs. 16 | auto-merge-dependabot: 17 | runs-on: ubuntu-latest 18 | steps: 19 | - uses: pascalgn/automerge-action@v0.13.1 20 | if: github.actor == 'dependabot[bot]' || github.actor == 'dependabot-preview[bot]' 21 | env: 22 | GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" 23 | MERGE_LABELS: "dependencies" 24 | MERGE_METHOD: "squash" # Sqush and merge 25 | MERGE_COMMIT_MESSAGE: "pull-request-title-and-description" 26 | MERGE_RETRY_SLEEP: "1200000" # Retry after 20m, enough time for check suites to run 27 | UPDATE_RETRIES: "6" 28 | UPDATE_METHOD: "rebase" # Rebase PR on base branch 29 | UPDATE_RETRY_SLEEP: "300000" -------------------------------------------------------------------------------- /.github/workflows/build_and_test.yml: -------------------------------------------------------------------------------- 1 | name: Build & Test 2 | on: 3 | pull_request: 4 | push: 5 | branches: 6 | - master 7 | schedule: 8 | # Run every hour. This helps detect flakiness, 9 | # and broken external dependencies. 10 | - cron: '0 * * * *' 11 | 12 | jobs: 13 | build_and_test_master: 14 | name: Build and Test Master ROS ${{ matrix.ros_version }} ${{ matrix.ros_distro }} 15 | runs-on: ubuntu-latest 16 | strategy: 17 | fail-fast: false 18 | matrix: 19 | ros_distro: [dashing] 20 | include: 21 | - ros_distro: dashing 22 | ubuntu_distro: bionic 23 | container: 24 | image: rostooling/setup-ros-docker:ubuntu-${{ matrix.ubuntu_distro }}-ros-${{ matrix.ros_distro }}-ros-base-latest 25 | env: 26 | # Needed for the CMakeLists.txt setup 27 | ROS_DISTRO: ${{ matrix.ros_distro }} 28 | ROS_VERSION: 2 29 | steps: 30 | # Needed to access the vcs repos file from the workspace 31 | - name: Checkout source 32 | uses: actions/checkout@v2 33 | - name: Run action-ros-ci to build and test 34 | uses: ros-tooling/action-ros-ci@0.1.2 35 | with: 36 | target-ros1-distro: ${{ env.ROS_VERSION == '1' && matrix.ros_distro || '' }} 37 | target-ros2-distro: ${{ env.ROS_VERSION == '2' && matrix.ros_distro || '' }} 38 | package-name: health_metric_collector 39 | vcs-repo-file-url: '' 40 | - name: Upload resulting colcon logs 41 | uses: actions/upload-artifact@v2.2.2 42 | with: 43 | name: colcon-logs-${{ matrix.ubuntu_distro }}-ros-${{ matrix.ros_distro }} 44 | path: ros_ws/log 45 | log_workflow_status_to_cloudwatch: 46 | runs-on: ubuntu-latest 47 | container: 48 | image: ubuntu:bionic 49 | needs: 50 | - build_and_test_master 51 | # Don't skip if prior steps failed, but don't run on a fork because it won't have access to AWS secrets 52 | if: ${{ always() && ! github.event.repository.fork && ! github.event.pull_request.head.repo.fork }} 53 | steps: 54 | - name: Configure AWS Credentials 55 | uses: aws-actions/configure-aws-credentials@v1 56 | with: 57 | aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} 58 | aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} 59 | aws-region: ${{ secrets.AWS_REGION }} 60 | - uses: ros-tooling/action-cloudwatch-metrics@0.0.5 61 | with: 62 | # Checks if any of the jobs have failed. 63 | # 64 | # needs.*.result is returns the list of all success statuses as an 65 | # array, i.e. ['success', 'failure, 'success'] 66 | # join() converts the array to a string 'successfailuresuccess' 67 | # contains() checks whether the string contains failure 68 | metric-value: ${{ ! contains(join(needs.*.result, ''), 'failure') && ! contains(join(needs.*.result, ''), 'cancelled') }} 69 | -------------------------------------------------------------------------------- /.github/workflows/build_and_test_release_latest.yml: -------------------------------------------------------------------------------- 1 | name: Build & Test release-latest 2 | on: 3 | schedule: 4 | # Run every hour. This helps detect flakiness, 5 | # and broken external dependencies. 6 | - cron: '0 * * * *' 7 | 8 | jobs: 9 | build_and_test_release_latest: 10 | name: Build and Test Release Latest ROS ${{ matrix.ros_version }} ${{ matrix.ros_distro }} 11 | runs-on: ubuntu-latest 12 | strategy: 13 | fail-fast: false 14 | matrix: 15 | ros_distro: [dashing] 16 | include: 17 | - ros_distro: dashing 18 | ubuntu_distro: bionic 19 | container: 20 | image: rostooling/setup-ros-docker:ubuntu-${{ matrix.ubuntu_distro }}-ros-${{ matrix.ros_distro }}-ros-base-latest 21 | env: 22 | # Needed for the CMakeLists.txt setup 23 | ROS_DISTRO: ${{ matrix.ros_distro }} 24 | ROS_VERSION: 2 25 | steps: 26 | # Needed to access the vcs repos file from the workspace 27 | - name: Checkout source 28 | uses: actions/checkout@v2 29 | - name: Run action-ros-ci to build and test 30 | uses: ros-tooling/action-ros-ci@0.1.2 31 | with: 32 | target-ros1-distro: ${{ env.ROS_VERSION == '1' && matrix.ros_distro || '' }} 33 | target-ros2-distro: ${{ env.ROS_VERSION == '2' && matrix.ros_distro || '' }} 34 | package-name: health_metric_collector 35 | # schedule runs against the default branch (master), so specify release-latest via repos file 36 | vcs-repo-file-url: "${{ github.workspace }}/.github/workflows/release_latest.repos" 37 | - name: Upload resulting colcon logs 38 | uses: actions/upload-artifact@v2.2.2 39 | with: 40 | name: colcon-logs-${{ matrix.ubuntu_distro }}-ros-${{ matrix.ros_distro }} 41 | path: ros_ws/log 42 | log_workflow_status_to_cloudwatch: 43 | runs-on: ubuntu-latest 44 | container: 45 | image: ubuntu:bionic 46 | needs: 47 | - build_and_test_release_latest 48 | # Don't skip if prior steps failed, but don't run on a fork because it won't have access to AWS secrets 49 | if: ${{ always() && ! github.event.repository.fork && ! github.event.pull_request.head.repo.fork }} 50 | steps: 51 | - name: Configure AWS Credentials 52 | uses: aws-actions/configure-aws-credentials@v1 53 | with: 54 | aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} 55 | aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} 56 | aws-region: ${{ secrets.AWS_REGION }} 57 | - uses: ros-tooling/action-cloudwatch-metrics@0.0.5 58 | with: 59 | metric-dimensions: >- 60 | [ 61 | { "Name": "github.event_name", "Value": "${{ github.event_name }}" }, 62 | { "Name": "github.ref", "Value": "release-latest" }, 63 | { "Name": "github.repository", "Value": "${{ github.repository }}" } 64 | ] 65 | # Checks if any of the jobs have failed. 66 | # 67 | # needs.*.result is returns the list of all success statuses as an 68 | # array, i.e. ['success', 'failure, 'success'] 69 | # join() converts the array to a string 'successfailuresuccess' 70 | # contains() checks whether the string contains failure 71 | metric-value: ${{ ! contains(join(needs.*.result, ''), 'failure') && ! contains(join(needs.*.result, ''), 'cancelled') }} 72 | -------------------------------------------------------------------------------- /.github/workflows/release_latest.repos: -------------------------------------------------------------------------------- 1 | repositories: 2 | health-metrics-collector-ros2: 3 | type: git 4 | url: https://github.com/aws-robotics/health-metrics-collector-ros2 5 | version: release-latest 6 | -------------------------------------------------------------------------------- /.rosinstall.master: -------------------------------------------------------------------------------- 1 | - git: 2 | uri: https://github.com/aws-robotics/utils-common.git 3 | local-name: utils-common 4 | version: master 5 | - git: 6 | uri: https://github.com/aws-robotics/utils-ros2.git 7 | local-name: utils-ros2 8 | version: master 9 | - git: 10 | uri: https://github.com/aws-robotics/monitoringmessages-ros2.git 11 | local-name: monitoringmessages-ros2 12 | version: master 13 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | ## Code of Conduct 2 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 3 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 4 | opensource-codeofconduct@amazon.com with any additional questions or comments. 5 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional 4 | documentation, we greatly value feedback and contributions from our community. 5 | 6 | Please read through this document before submitting any issues or pull requests to ensure we have all the necessary 7 | information to effectively respond to your bug report or contribution. 8 | 9 | 10 | ## Reporting Bugs/Feature Requests 11 | 12 | We welcome you to use the GitHub issue tracker to report bugs or suggest features. 13 | 14 | When filing an issue, please check [existing open](https://github.com/aws-robotics/health-metrics-collector-ros2/issues), or [recently closed](https://github.com/aws-robotics/health-metrics-collector-ros2/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aclosed%20), issues to make sure somebody else hasn't already 15 | reported the issue. Please try to include as much information as you can. Details like these are incredibly useful: 16 | 17 | * A reproducible test case or series of steps 18 | * The version of our code being used 19 | * Any modifications you've made relevant to the bug 20 | * Anything unusual about your environment or deployment 21 | 22 | 23 | ## Contributing via Pull Requests 24 | Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that: 25 | 26 | 1. You are working against the latest source on the *master* branch. 27 | 2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already. 28 | 3. You open an issue to discuss any significant work - we would hate for your time to be wasted. 29 | 30 | To send us a pull request, please: 31 | 32 | 1. Fork the repository. 33 | 2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change. 34 | 3. Ensure local tests pass. 35 | 4. Commit to your fork using clear commit messages. 36 | 5. Send us a pull request, answering any default questions in the pull request interface. 37 | 6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation. 38 | 39 | GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and 40 | [creating a pull request](https://help.github.com/articles/creating-a-pull-request/). 41 | 42 | 43 | ## Finding contributions to work on 44 | Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any ['help wanted'](https://github.com/aws-robotics/health-metrics-collector-ros2/labels/help%20wanted) issues is a great place to start. 45 | 46 | 47 | ## Code of Conduct 48 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 49 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 50 | opensource-codeofconduct@amazon.com with any additional questions or comments. 51 | 52 | 53 | ## Security issue notifications 54 | If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue. 55 | 56 | 57 | ## Licensing 58 | 59 | See the [LICENSE](https://github.com/aws-robotics/health-metrics-collector-ros2/blob/master/LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution. 60 | 61 | We may ask you to sign a [Contributor License Agreement (CLA)](http://en.wikipedia.org/wiki/Contributor_License_Agreement) for larger changes. 62 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | health-metrics-collector-ros2 2 | Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # health_metric_collector 2 | 3 | ## Overview 4 | This `health_metric_collector` ROS node collects system metrics and publishes them to `/metrics` topic. The `cloudwatch_metrics_collector` node is subscribed to this topic and will publish the metrics to AWS CloudWatch when it is instantiated. 5 | 6 | **Keywords**: ROS, ROS2, AWS, CloudWatch, Metrics 7 | 8 | ### License 9 | The source code is released under an [Apache 2.0]. 10 | 11 | **Author**: AWS RoboMaker
12 | **Affiliation**: [Amazon Web Services (AWS)]
13 | 14 | RoboMaker cloud extensions rely on third-party software licensed under open-source licenses and are provided for demonstration purposes only. Incorporation or use of RoboMaker cloud extensions in connection with your production workloads or commercial product(s) or devices may affect your legal rights or obligations under the applicable open-source licenses. License information for this repository can be found [here](https://github.com/aws-robotics/health-metrics-collector-ros2/blob/master/LICENSE). AWS does not provide support for this cloud extension. You are solely responsible for how you configure, deploy, and maintain this cloud extension in your workloads or commercial product(s) or devices. 15 | 16 | ### Supported ROS Distributions 17 | - Dashing 18 | 19 | ## Installation 20 | 21 | ### AWS Credentials 22 | You will need to create an AWS Account and configure the credentials to be able to communicate with AWS services. You may find [AWS Configuration and Credential Files] helpful. Specifying AWS [credentials by setting environment variables](https://docs.aws.amazon.com/cli/latest/userguide/cli-environment.html) is not supported. 23 | 24 | This node will require the following AWS account IAM role permissions: 25 | - `cloudwatch:PutMetricData` 26 | 27 | ### Building from Source 28 | 29 | To build from source you'll need to create a new workspace, clone and checkout the latest release branch of this repository, install all the dependencies, and compile. If you need the latest development features you can clone from the `master` branch instead of the latest release branch. While we guarantee the release branches are stable, __the `master` should be considered to have an unstable build__ due to ongoing development. 30 | 31 | - Create a ROS workspace and a source directory 32 | 33 | mkdir -p ~/ros-workspace/src 34 | 35 | - Clone the package into the source directory . 36 | 37 | cd ~/ros-workspace/src 38 | git clone https://github.com/aws-robotics/health-metrics-collector-ros2.git -b release-latest 39 | 40 | - Install dependencies 41 | 42 | cd ~/ros-workspace 43 | sudo apt-get update && rosdep update 44 | rosdep install --from-paths src --ignore-src -r -y 45 | 46 | _Note: If building the master branch instead of a release branch you may need to also checkout and build the master branches of the packages this package depends on._ 47 | 48 | - Build the packages 49 | 50 | cd ~/ros-workspace && colcon build 51 | 52 | - Configure ROS library Path 53 | 54 | source ~/ros-workspace/install/local_setup.bash 55 | 56 | - Run the unit tests 57 | 58 | colcon test --packages-select health_metric_collector && colcon test-result --all 59 | 60 | 61 | ## Launch Files 62 | An example launch file called `sample_application.launch` is included in this project that gives an example of how you can include this node in your project together with the [`cloudwatch_metrics_collector`] node. 63 | 64 | 65 | ## Usage 66 | 67 | ### Run the node 68 | - `ros2 launch health_metric_collector health_metric_collector.launch.py` 69 | 70 | 71 | ### Running the sample application 72 | To launch the sample application for the metrics node you can run the following command: 73 | 74 | - `ros2 launch health_metric_collector sample_application.launch.py --screen` 75 | 76 | This will launch `cloudwatch_metrics_collector` too, and will start emitting metrics to Amazon CloudWatch. 77 | 78 | ## Configuration file and Parameters 79 | The `health_metric_collector` node receives an interval parameter that indicates the frequency in which it should sample metrics. e.g. interval=5 indicates sampling every five seconds. The default value is 5. 80 | 81 | #### Supported Metrics Types 82 | - Free RAM (in MB) 83 | - Total RAM (in MB) 84 | - Total cpu usage (percentage) 85 | - Per core cpu usage (percentage) 86 | - Uptime (in sec) 87 | - Number of processes 88 | 89 | 90 | ## Node 91 | 92 | ### health_metric_collector 93 | 94 | #### Published Topics 95 | - **`/metrics`** 96 | 97 | #### Subscribed Topics 98 | None 99 | 100 | #### Services 101 | None 102 | 103 | [`cloudwatch_metrics_collector`]: https://github.com/aws-robotics/cloudwatchmetrics-ros2 104 | [Amazon Web Services (AWS)]: https://aws.amazon.com/ 105 | [Apache 2.0]: https://aws.amazon.com/apache-2-0/ 106 | [AWS Configuration and Credential Files]: https://docs.aws.amazon.com/cli/latest/userguide/cli-config-files.html 107 | [Issue Tracker]: https://github.com/aws-robotics/health-metrics-collector-ros2/issues 108 | [ROS]: http://www.ros.org 109 | -------------------------------------------------------------------------------- /health_metric_collector/CHANGELOG.rst: -------------------------------------------------------------------------------- 1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 2 | Changelog for package health_metric_collector 3 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 4 | 5 | 3.0.1 (2019-09-20) 6 | ------------------ 7 | * Bump version to 3.0.1 8 | * Replacing sample_application.launch with an equivalent launch script 9 | * Guard test targets with if(BUILD_TESTING) 10 | * remove changelog for new release 11 | * Add launch dependencies 12 | * Update version to 3.0.0 for first ROS2 release (`#5 `_) 13 | * Update version to 2.0.1 for consistency with health-metrics-collector-ros1 14 | * Bumping version to 3.0.0 and upgrading package.xml format to 3 15 | * Update changelog 16 | * Allow undeclared params and add default ones to the yaml config file. 17 | * Add unit tests (equivalent to the ROS1 version) 18 | * Remove cmake-build-debug folder 19 | * Rename package, make launch file ROS1 compatible 20 | - Rename package to health_metric_collector, removing the _node suffix 21 | to keep this package consistent with all our others (where github repo, 22 | folder name and package name are all the same). 23 | - Improve launch file to be the same as ROS1 where users can override 24 | node_name or config_file. 25 | * Merge pull request `#2 `_ from aws-robotics/namespace-fixup 26 | Fixes the namespacing that was mistakenly added for several files during the conversion. 27 | * Fixes the namespacing that was mistakenly added for several files during the conversion. 28 | * Adding basic implementation 29 | * Contributors: AAlon, Avishay Alon, M M, Nick Burek, Tim Robinson, burekn 30 | -------------------------------------------------------------------------------- /health_metric_collector/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | 3 | project(health_metric_collector) 4 | 5 | 6 | # Default to C++14 7 | if (NOT CMAKE_CXX_STANDARD) 8 | set(CMAKE_CXX_STANDARD 14) 9 | endif () 10 | 11 | if (CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") 12 | add_compile_options(-Wall -Wextra -Wpedantic) 13 | endif () 14 | 15 | 16 | find_package(ament_cmake REQUIRED) 17 | find_package(rclcpp REQUIRED) 18 | find_package(aws_common REQUIRED) 19 | find_package(aws_ros2_common REQUIRED) 20 | find_package(ros_monitoring_msgs REQUIRED) 21 | 22 | add_definitions(-DUSE_IMPORT_EXPORT) 23 | 24 | set(HEALTH_METRIC_COLLECTOR_LIBRARY_TARGET ${PROJECT_NAME}_lib) 25 | 26 | ########### 27 | ## Build ## 28 | ########### 29 | 30 | include_directories( 31 | include 32 | ${rclcpp_INCLUDE_DIRS} 33 | ${aws_ros2_common_INCLUDE_DIRS} 34 | ${AWSSDK_INCLUDE_DIRS} 35 | ${aws_common_INCLUDE_DIRS} 36 | ${ros_monitoring_msgs_INCLUDE_DIRS} 37 | ) 38 | 39 | add_library(${HEALTH_METRIC_COLLECTOR_LIBRARY_TARGET} 40 | src/cpu_data.cpp 41 | src/cpu_metric_collector.cpp 42 | src/cpu_stats.cpp 43 | src/metric_manager.cpp 44 | src/sys_info_collector.cpp 45 | ) 46 | 47 | ament_target_dependencies(${HEALTH_METRIC_COLLECTOR_LIBRARY_TARGET} 48 | rclcpp 49 | aws_common 50 | aws_ros2_common 51 | ros_monitoring_msgs 52 | rosidl_typesupport_cpp 53 | ) 54 | 55 | add_executable(${PROJECT_NAME} src/collector.cpp) 56 | 57 | set(LIB_DEPS 58 | ${rclcpp_LIBRARIES} 59 | ${aws_common_LIBRARIES} 60 | ${aws_ros2_common_LIBRARIES} 61 | ${ros_monitoring_msgs_LIBRARIES} 62 | ) 63 | 64 | target_link_libraries(${PROJECT_NAME} ${LIB_DEPS}) 65 | 66 | ament_target_dependencies(${PROJECT_NAME} ${HEALTH_METRIC_COLLECTOR_LIBRARY_TARGET}) 67 | 68 | target_link_libraries(${PROJECT_NAME} ${HEALTH_METRIC_COLLECTOR_LIBRARY_TARGET}) 69 | 70 | ############# 71 | ## Install ## 72 | ############# 73 | 74 | ## Mark executables and/or libraries for installation 75 | install(TARGETS ${PROJECT_NAME} ${HEALTH_METRIC_COLLECTOR_LIBRARY_TARGET} 76 | ARCHIVE DESTINATION lib 77 | LIBRARY DESTINATION lib 78 | # According to https://answers.ros.org/question/280127/ros2-ros2-run-package-executable-cannot-find-executable/ 79 | # executables are now being installed to the library directory under project name 80 | RUNTIME DESTINATION lib/${PROJECT_NAME} 81 | ) 82 | 83 | ## Mark cpp header files for installation 84 | install( 85 | DIRECTORY include/ 86 | DESTINATION include 87 | FILES_MATCHING PATTERN "*.h" 88 | ) 89 | 90 | ### Mark other files for installation (e.g. launch and bag files, etc.) 91 | install(DIRECTORY launch/ DESTINATION share/${PROJECT_NAME}/launch) 92 | install(DIRECTORY config/ DESTINATION share/${PROJECT_NAME}/config) 93 | 94 | ############# 95 | ## Tests ## 96 | ############# 97 | 98 | if(BUILD_TESTING) 99 | find_package(ament_cmake_gmock REQUIRED) 100 | 101 | ament_add_gmock(test_health_metric_collector 102 | test/health_metric_collector_test.cpp) 103 | target_include_directories(test_health_metric_collector 104 | PRIVATE include) 105 | target_link_libraries(test_health_metric_collector 106 | ${HEALTH_METRIC_COLLECTOR_LIBRARY_TARGET} 107 | ${LIB_DEPS}) 108 | endif() 109 | 110 | ament_package() 111 | -------------------------------------------------------------------------------- /health_metric_collector/LICENSE.txt: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright 2018 Amazon.com, Inc. or its affiliates 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | 204 | -------------------------------------------------------------------------------- /health_metric_collector/NOTICE.txt: -------------------------------------------------------------------------------- 1 | Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | This product includes software developed by 4 | Amazon Technologies, Inc (http://www.amazon.com/). 5 | 6 | -------------------------------------------------------------------------------- /health_metric_collector/config/sample_configuration.yaml: -------------------------------------------------------------------------------- 1 | health_metric_collector: 2 | ros__parameters: 3 | interval: 5.0 4 | robot_id: "Turtlebot3" 5 | -------------------------------------------------------------------------------- /health_metric_collector/include/health_metric_collector/collect_and_publish.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | #include 17 | #include 18 | 19 | #include 20 | 21 | /** 22 | * @brief activates collectors and then publishes metrics. 23 | */ 24 | class CollectAndPublish 25 | { 26 | public: 27 | /** 28 | * @brief Constructor 29 | * 30 | * @param mg the metric manager that publishes collected metrics. 31 | * @param c a list of metrics collectors. 32 | */ 33 | CollectAndPublish( 34 | std::shared_ptr mg, 35 | std::vector> & c 36 | ) : mg_(mg), collectors_(c) {} 37 | 38 | /** 39 | * @brief activates all collectors and then publishes the metrics. 40 | * 41 | * @param event time event in which this run occurs. 42 | */ 43 | void Publish() 44 | { 45 | for (auto c : collectors_) { 46 | c->Collect(); 47 | } 48 | mg_->Publish(); 49 | } 50 | 51 | private: 52 | std::shared_ptr mg_; 53 | const std::vector> & 54 | collectors_; 55 | }; 56 | -------------------------------------------------------------------------------- /health_metric_collector/include/health_metric_collector/cpu_data.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | #pragma once 17 | 18 | #include 19 | 20 | /** 21 | * struct for holding CPU time in each cpu state. 22 | */ 23 | struct CPUData 24 | { 25 | enum CPUStates { 26 | kUser = 0, 27 | kNice, 28 | kSystem, 29 | kIdle, 30 | kIOWait, 31 | kIrq, 32 | kSoftIrq, 33 | kSteal, 34 | kGuest, 35 | kGuestNice, 36 | kNumCpuStates 37 | }; 38 | 39 | std::string cpu; 40 | size_t times[kNumCpuStates]; 41 | 42 | size_t GetIdleTime() const; 43 | size_t GetActiveTime() const; 44 | }; 45 | -------------------------------------------------------------------------------- /health_metric_collector/include/health_metric_collector/cpu_metric_collector.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | #pragma once 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | 24 | /** 25 | * collects cpu usage metric. 26 | */ 27 | class CPUMetricCollector : public MetricCollectorInterface 28 | { 29 | public: 30 | /** 31 | * @brief Constructor. 32 | * 33 | * @param m metric manager which creates and aggregates metrics. 34 | */ 35 | CPUMetricCollector(std::shared_ptr m) 36 | : MetricCollectorInterface(m) {} 37 | 38 | /** 39 | * @brief activates metrics collection. 40 | */ 41 | void Collect() override final; 42 | 43 | private: 44 | void CollectCpuUsage(const std::vector & entries1, 45 | const std::vector & entries2); 46 | 47 | std::shared_ptr old_; 48 | std::shared_ptr new_; 49 | }; 50 | -------------------------------------------------------------------------------- /health_metric_collector/include/health_metric_collector/cpu_stats.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | #pragma once 17 | 18 | #include 19 | 20 | #include 21 | #include 22 | 23 | /** 24 | * Parse /proc/stat. 25 | */ 26 | class CPUStats 27 | { 28 | public: 29 | /** 30 | * @brief return cpu data entries. 31 | */ 32 | const std::vector & GetEntries() const { return entries_; } 33 | 34 | /** 35 | * @brief parse /proc/stats. 36 | */ 37 | void ReadStatsCPU(); 38 | 39 | private: 40 | std::vector entries_; 41 | }; 42 | -------------------------------------------------------------------------------- /health_metric_collector/include/health_metric_collector/metric_collector.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | #pragma once 17 | 18 | #include 19 | 20 | /** 21 | * @brief Interface for a metrics collector. 22 | */ 23 | class MetricCollectorInterface 24 | { 25 | public: 26 | /** 27 | * @brief Constructor. 28 | */ 29 | MetricCollectorInterface( 30 | std::shared_ptr mgr 31 | ) : mgr_(mgr) {} 32 | 33 | /** 34 | * @brief callback for collecting metrics. 35 | */ 36 | virtual void Collect() = 0; 37 | 38 | protected: 39 | /** 40 | * @brief creates metric entries and publishes them. 41 | */ 42 | std::shared_ptr mgr_; 43 | }; 44 | -------------------------------------------------------------------------------- /health_metric_collector/include/health_metric_collector/metric_manager.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | #pragma once 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | 25 | /** 26 | * @brief Interface for MetricManager. 27 | */ 28 | class MetricManagerInterface { 29 | public: 30 | /** 31 | * @brief add global dimension (applies to all metrics). 32 | */ 33 | virtual void AddDimension(const std::string &name, const std::string &value) = 0; 34 | 35 | /** 36 | * @brief create a metric. 37 | */ 38 | virtual ros_monitoring_msgs::msg::MetricData CreateMetric() const = 0; 39 | 40 | /** 41 | * @brief add a metric to list of metrics to be published. 42 | * 43 | * @param md a metric. 44 | */ 45 | virtual void AddMetric(ros_monitoring_msgs::msg::MetricData md) = 0; 46 | 47 | /** 48 | * @brief publishes all metrics and then discards them. 49 | */ 50 | virtual void Publish() = 0; 51 | 52 | /** @brief destructor. */ 53 | virtual ~MetricManagerInterface() {} 54 | }; 55 | 56 | /** 57 | * @brief Create, aggregate and publish metrics to ros topic. 58 | **/ 59 | class MetricManager : public MetricManagerInterface { 60 | public: 61 | explicit MetricManager( 62 | rclcpp::Node::SharedPtr node, 63 | std::string metrics_topic_name, 64 | int topic_buffer_size 65 | ) : 66 | node_(node), 67 | publisher_(node->create_publisher(metrics_topic_name, topic_buffer_size)) {} 68 | 69 | virtual void AddDimension(const std::string &name, const std::string &value) override final; 70 | 71 | virtual ros_monitoring_msgs::msg::MetricData CreateMetric() const override final; 72 | 73 | virtual void AddMetric(ros_monitoring_msgs::msg::MetricData md) override final; 74 | 75 | virtual void Publish() override final; 76 | 77 | private: 78 | rclcpp::Node::SharedPtr node_; 79 | rclcpp::Publisher::SharedPtr publisher_; 80 | ros_monitoring_msgs::msg::MetricList mlist_; 81 | ros_monitoring_msgs::msg::MetricData dimensions_; 82 | }; 83 | -------------------------------------------------------------------------------- /health_metric_collector/include/health_metric_collector/sys_info_collector.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | #pragma once 17 | 18 | #include 19 | #include 20 | 21 | 22 | /** 23 | * @brief collects metrics from sysinfo. 24 | * 25 | * Metrics collected: 26 | * system uptime, free ram, total ram, process count 27 | */ 28 | class SysInfoCollector : public MetricCollectorInterface 29 | { 30 | public: 31 | SysInfoCollector(std::shared_ptr m) 32 | : MetricCollectorInterface(m) {} 33 | 34 | void Collect() override final; 35 | 36 | private: 37 | void AddMetric(const std::string & name, const double value, const std::string & unit); 38 | }; 39 | -------------------------------------------------------------------------------- /health_metric_collector/launch/health_metric_collector.launch.py: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"). 4 | # You may not use this file except in compliance with the License. 5 | # A copy of the License is located at 6 | # 7 | # http://aws.amazon.com/apache2.0 8 | # 9 | # or in the "license" file accompanying this file. This file is distributed 10 | # on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | # express or implied. See the License for the specific language governing 12 | # permissions and limitations under the License. 13 | 14 | import os 15 | 16 | import launch 17 | from ament_index_python.packages import get_package_share_directory 18 | from launch import LaunchDescription 19 | from launch_ros.actions import Node 20 | 21 | 22 | def generate_launch_description(): 23 | default_config = os.path.join(get_package_share_directory('health_metric_collector'), 24 | 'config', 'sample_configuration.yaml') 25 | parameters = [launch.substitutions.LaunchConfiguration("config_file")] 26 | return LaunchDescription([ 27 | launch.actions.DeclareLaunchArgument( 28 | "node_name", 29 | default_value="health_metric_collector", 30 | ), 31 | launch.actions.DeclareLaunchArgument( 32 | "config_file", 33 | default_value=default_config 34 | ), 35 | Node( 36 | package='health_metric_collector', 37 | node_executable='health_metric_collector', 38 | node_name=launch.substitutions.LaunchConfiguration('node_name'), 39 | parameters=parameters, 40 | output='screen' 41 | ), 42 | ]) 43 | -------------------------------------------------------------------------------- /health_metric_collector/launch/sample_application.launch.py: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"). 4 | # You may not use this file except in compliance with the License. 5 | # A copy of the License is located at 6 | # 7 | # http://aws.amazon.com/apache2.0 8 | # 9 | # or in the "license" file accompanying this file. This file is distributed 10 | # on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 | # express or implied. See the License for the specific language governing 12 | # permissions and limitations under the License. 13 | 14 | import os 15 | 16 | import launch 17 | from ament_index_python.packages import get_package_share_directory 18 | from launch import LaunchDescription 19 | from launch.substitutions import ThisLaunchFileDir 20 | 21 | def generate_launch_description(): 22 | hmc_launch = launch.actions.IncludeLaunchDescription( 23 | launch.launch_description_sources.PythonLaunchDescriptionSource( 24 | [ThisLaunchFileDir(), '/health_metric_collector.launch.py']) 25 | ) 26 | cw_metrics_node_launch = launch.actions.IncludeLaunchDescription( 27 | launch.launch_description_sources.PythonLaunchDescriptionSource( 28 | os.path.join(get_package_share_directory('cloudwatch_metrics_collector'), 'launch', 'cloudwatch_metrics_collector.launch.py')) 29 | ) 30 | return LaunchDescription([ 31 | hmc_launch, 32 | cw_metrics_node_launch 33 | ]) 34 | -------------------------------------------------------------------------------- /health_metric_collector/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | health_metric_collector 4 | 3.0.1 5 | Package providing a ROS node for sending health metrics to Cloudwatch Metrics 6 | 7 | AWS RoboMaker 8 | AWS RoboMaker 9 | 10 | Apache 2.0 11 | 12 | ament_cmake 13 | 14 | rclcpp 15 | ros_monitoring_msgs 16 | aws_ros2_common 17 | aws_common 18 | 19 | launch_ros 20 | launch 21 | rclcpp 22 | ros_monitoring_msgs 23 | aws_common 24 | 25 | ament_cmake_gmock 26 | 27 | 28 | ament_cmake 29 | 30 | 31 | -------------------------------------------------------------------------------- /health_metric_collector/src/collector.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | #include 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #include 28 | #include 29 | 30 | 31 | using namespace Aws::Client; 32 | using namespace std::chrono_literals; 33 | using namespace ros_monitoring_msgs::msg; 34 | 35 | 36 | #define DEFAULT_INTERVAL_SEC 5 37 | #define TOPIC_BUFFER_SIZE 1000 38 | #define INTERVAL_PARAM_NAME "interval" 39 | #define ROBOT_ID_DIMENSION "robot_id" 40 | #define CATEGORY_DIMENSION "category" 41 | #define HEALTH_CATEGORY "RobotHealth" 42 | #define DEFAULT_ROBOT_ID "Default_Robot" 43 | #define DEFAULT_NODE_NAME "health_metric_collector" 44 | #define METRICS_TOPIC_NAME "metrics" 45 | 46 | 47 | int main(int argc, char ** argv) 48 | { 49 | rclcpp::init(argc, argv); 50 | 51 | rclcpp::NodeOptions node_options; 52 | node_options.allow_undeclared_parameters(true); 53 | node_options.automatically_declare_parameters_from_overrides(true); 54 | 55 | auto node = rclcpp::Node::make_shared(DEFAULT_NODE_NAME, std::string(), node_options); 56 | 57 | auto param_reader = std::make_shared(node); 58 | 59 | // get interval param 60 | double interval = DEFAULT_INTERVAL_SEC; 61 | param_reader->ReadParam(ParameterPath(INTERVAL_PARAM_NAME), interval); 62 | 63 | // get robot id 64 | std::string robot_id = DEFAULT_ROBOT_ID; 65 | param_reader->ReadParam(ParameterPath(ROBOT_ID_DIMENSION), robot_id); 66 | 67 | // advertise 68 | AWS_LOG_INFO(__func__, "Starting Health Metric Collector Node..."); 69 | auto mg = std::make_shared(node, METRICS_TOPIC_NAME, TOPIC_BUFFER_SIZE); 70 | mg->AddDimension(ROBOT_ID_DIMENSION, robot_id); 71 | mg->AddDimension(CATEGORY_DIMENSION, HEALTH_CATEGORY); 72 | 73 | std::vector> collectors; 74 | auto cpu_collector = std::make_shared(mg); 75 | collectors.push_back(cpu_collector); 76 | 77 | auto sys_collector = std::make_shared(mg); 78 | collectors.push_back(sys_collector); 79 | 80 | // start metrics collection 81 | CollectAndPublish f(mg, collectors); 82 | auto timer = node->create_wall_timer(1s, [&f]{f.Publish();}); 83 | 84 | rclcpp::spin(node); 85 | 86 | AWS_LOG_INFO(__func__, "Shutting down Health Metric Collector Node..."); 87 | return 0; 88 | } 89 | -------------------------------------------------------------------------------- /health_metric_collector/src/cpu_data.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | #include 17 | 18 | size_t CPUData::GetActiveTime() const 19 | { 20 | return times[kUser] + times[kNice] + times[kSystem] + times[kIrq] + times[kSoftIrq] + 21 | times[kSteal] + times[kGuest] + times[kGuestNice]; 22 | } 23 | 24 | size_t CPUData::GetIdleTime() const { return times[kIdle] + times[kIOWait]; } 25 | -------------------------------------------------------------------------------- /health_metric_collector/src/cpu_metric_collector.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | #include 21 | #include 22 | 23 | using namespace ros_monitoring_msgs::msg; 24 | 25 | #define BASE_METRIC_NAME "cpu_usage_" 26 | 27 | 28 | void CPUMetricCollector::Collect() 29 | { 30 | // new snapshot 31 | new_ = std::make_shared(); 32 | new_->ReadStatsCPU(); 33 | 34 | if (old_) { 35 | CollectCpuUsage(old_->GetEntries(), new_->GetEntries()); 36 | } 37 | 38 | old_ = new_; 39 | new_.reset(); 40 | } 41 | 42 | void CPUMetricCollector::CollectCpuUsage(const std::vector & entries1, 43 | const std::vector & entries2) 44 | { 45 | const size_t num_of_entries = std::min(entries1.size(), entries2.size()); 46 | 47 | for (size_t i = 0; i < num_of_entries; ++i) { 48 | const CPUData & e1 = entries1[i]; 49 | const CPUData & e2 = entries2[i]; 50 | 51 | const auto active_time = static_cast(e2.GetActiveTime() - e1.GetActiveTime()); 52 | const auto idle_time = static_cast(e2.GetIdleTime() - e1.GetIdleTime()); 53 | const float total_time = active_time + idle_time; 54 | const float usage = 100.f * active_time / total_time; 55 | 56 | MetricData md = mgr_->CreateMetric(); 57 | md.metric_name = BASE_METRIC_NAME + entries1[i].cpu; 58 | md.unit = MetricData::UNIT_PERCENTAGE; 59 | md.value = usage; 60 | mgr_->AddMetric(md); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /health_metric_collector/src/cpu_stats.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | #include 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | void CPUStats::ReadStatsCPU() 24 | { 25 | std::ifstream file_stat("/proc/stat"); 26 | 27 | std::string line; 28 | 29 | const std::string str_tot("tot"); 30 | const std::string str_cpu("cpu"); 31 | const std::size_t len_str_cpu = str_cpu.size(); 32 | 33 | while (std::getline(file_stat, line)) { 34 | // cpu stats line found 35 | if (!line.compare(0, len_str_cpu, str_cpu)) { 36 | std::istringstream ss(line); 37 | 38 | // store entry 39 | entries_.emplace_back(CPUData()); 40 | CPUData & entry = entries_.back(); 41 | 42 | // read cpu label 43 | ss >> entry.cpu; 44 | 45 | // remove "cpu" from the label when it's a processor number 46 | if (entry.cpu.size() > len_str_cpu) { 47 | entry.cpu.erase(0, len_str_cpu); 48 | entry.cpu = "core_" + entry.cpu; 49 | } 50 | // replace "cpu" with "tot" when it's total values 51 | else { 52 | entry.cpu = str_tot; 53 | } 54 | // read times 55 | for (int i = 0; i < CPUData::kNumCpuStates; ++i) { 56 | ss >> entry.times[i]; 57 | } 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /health_metric_collector/src/metric_manager.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | #include 17 | #include 18 | 19 | #include 20 | 21 | using namespace ros_monitoring_msgs::msg; 22 | 23 | 24 | MetricData MetricManager::CreateMetric() const 25 | { 26 | MetricData md; 27 | // FIXME use builtin_interfaces.msg.time and node->now() 28 | md.header.stamp = node_->now(); 29 | md.time_stamp = md.header.stamp; 30 | md.dimensions = dimensions_.dimensions; 31 | return md; 32 | } 33 | 34 | void MetricManager::AddDimension(const std::string & name, const std::string & value) 35 | { 36 | MetricDimension dim; 37 | dim.name = name; 38 | dim.value = value; 39 | dimensions_.dimensions.push_back(dim); 40 | } 41 | 42 | void MetricManager::AddMetric(MetricData md) { mlist_.metrics.push_back(md); } 43 | 44 | void MetricManager::Publish() 45 | { 46 | publisher_->publish(mlist_); 47 | mlist_.metrics.clear(); 48 | } 49 | -------------------------------------------------------------------------------- /health_metric_collector/src/sys_info_collector.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | #include 21 | #include 22 | 23 | using namespace ros_monitoring_msgs::msg; 24 | 25 | #define MEGA (1000000) 26 | 27 | 28 | void SysInfoCollector::Collect() 29 | { 30 | // Obtain system statistics 31 | struct sysinfo si 32 | { 33 | }; 34 | sysinfo(&si); 35 | 36 | AddMetric("system_uptime", si.uptime, MetricData::UNIT_SEC); 37 | AddMetric("free_ram", si.freeram / MEGA, MetricData::UNIT_MEGABYTES); 38 | AddMetric("total_ram", si.totalram / MEGA, MetricData::UNIT_MEGABYTES); 39 | AddMetric("process_count", si.procs, MetricData::UNIT_NONE); 40 | } 41 | 42 | void SysInfoCollector::AddMetric(const std::string & name, const double value, 43 | const std::string & unit) 44 | { 45 | MetricData md = mgr_->CreateMetric(); 46 | md.metric_name = name; 47 | md.unit = unit; 48 | md.value = value; 49 | mgr_->AddMetric(md); 50 | } 51 | -------------------------------------------------------------------------------- /health_metric_collector/test/health_metric_collector_test.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"). 5 | * You may not use this file except in compliance with the License. 6 | * A copy of the License is located at 7 | * 8 | * http://aws.amazon.com/apache2.0 9 | * 10 | * or in the "license" file accompanying this file. This file is distributed 11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 | * express or implied. See the License for the specific language governing 13 | * permissions and limitations under the License. 14 | */ 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #include 26 | 27 | using namespace ros_monitoring_msgs::msg; 28 | using ::testing::Return; 29 | 30 | class MockMetricManager : public MetricManagerInterface 31 | { 32 | public: 33 | MOCK_METHOD0(Publish, void()); 34 | 35 | MOCK_METHOD2(AddDimension, void(const std::string &, const std::string &)); 36 | 37 | MOCK_CONST_METHOD0(CreateMetric, MetricData()); 38 | 39 | MOCK_METHOD1(AddMetric, void(MetricData)); 40 | }; 41 | 42 | class MockMetricCollector : public MetricCollectorInterface 43 | { 44 | public: 45 | MockMetricCollector(std::shared_ptr m) : MetricCollectorInterface(m) {} 46 | MOCK_METHOD0(Collect, void()); 47 | }; 48 | 49 | 50 | TEST(CollectorSuite, Child) 51 | { 52 | auto mg = std::make_shared(); 53 | 54 | std::vector> collectors; 55 | auto mc = std::make_shared(mg); 56 | collectors.push_back(mc); 57 | 58 | // start metrics collection 59 | CollectAndPublish f(mg, collectors); 60 | 61 | MetricData md; 62 | ON_CALL(*mg, CreateMetric()).WillByDefault(Return(md)); 63 | EXPECT_CALL(*mg, Publish()).Times(1); 64 | EXPECT_CALL(*mc, Collect()).Times(1); 65 | 66 | f.Publish(); 67 | } 68 | 69 | TEST(CollectorSuite, sysinfo) 70 | { 71 | auto mg = std::make_shared(); 72 | MetricData md; 73 | ON_CALL(*mg, CreateMetric()).WillByDefault(Return(md)); 74 | 75 | EXPECT_CALL(*mg, AddMetric(testing::_)).Times(4); 76 | SysInfoCollector sys_collector(mg); 77 | sys_collector.Collect(); 78 | } 79 | 80 | TEST(CollectorSuite, cpu_usage_0) 81 | { 82 | auto mg = std::make_shared(); 83 | MetricData md; 84 | ON_CALL(*mg, CreateMetric()).WillByDefault(Return(md)); 85 | 86 | EXPECT_CALL(*mg, AddMetric(testing::_)).Times(0); 87 | 88 | CPUMetricCollector cpu_collector(mg); 89 | cpu_collector.Collect(); 90 | } 91 | 92 | TEST(CollectorSuite, cpu_usage_1) 93 | { 94 | auto mg = std::make_shared(); 95 | MetricData md; 96 | ON_CALL(*mg, CreateMetric()).WillByDefault(Return(md)); 97 | 98 | EXPECT_CALL(*mg, AddMetric(testing::_)).Times(testing::AtLeast(1)); 99 | 100 | CPUMetricCollector cpu_collector(mg); 101 | cpu_collector.Collect(); 102 | cpu_collector.Collect(); 103 | } 104 | 105 | int main(int argc, char ** argv) 106 | { 107 | testing::InitGoogleTest(&argc, argv); 108 | rclcpp::init(argc, argv); 109 | 110 | return RUN_ALL_TESTS(); 111 | } 112 | --------------------------------------------------------------------------------