From 395ee91758c3717f2fa92f2ae2d923c82261dee3 Mon Sep 17 00:00:00 2001 From: stuart nelson Date: Tue, 1 Feb 2022 10:00:10 +0100 Subject: [PATCH] [elastic-agent] initial apm instrumentation (#29031) --- NOTICE.txt | 1180 +++++++++++++++-- go.mod | 8 +- go.sum | 19 +- .../pkg/agent/application/application.go | 20 +- .../application/fleet_server_bootstrap.go | 15 +- .../gateway/fleet/fleet_gateway.go | 2 +- .../gateway/fleet/fleet_gateway_test.go | 2 +- .../fleetserver/fleet_gateway_local.go | 2 +- .../pkg/agent/application/local_mode.go | 5 +- .../pkg/agent/application/managed_mode.go | 8 +- .../agent/application/managed_mode_test.go | 4 +- .../pkg/agent/application/once.go | 8 +- .../pkg/agent/application/periodic.go | 3 +- .../handlers/handler_action_policy_change.go | 2 +- .../handler_action_policy_change_test.go | 2 +- .../handlers/handler_action_unenroll.go | 2 +- .../pipeline/dispatcher/dispatcher.go | 19 +- .../pipeline/dispatcher/dispatcher_test.go | 10 +- .../pipeline/emitter/controller.go | 69 +- .../application/pipeline/emitter/emitter.go | 16 +- .../agent/application/pipeline/pipeline.go | 12 +- .../application/pipeline/router/router.go | 5 +- .../pipeline/router/router_test.go | 20 +- .../pipeline/stream/operator_stream.go | 16 +- .../application/upgrade/step_download.go | 11 +- .../pkg/agent/application/upgrade/upgrade.go | 4 + .../elastic-agent/pkg/agent/cmd/enroll_cmd.go | 29 +- x-pack/elastic-agent/pkg/agent/cmd/inspect.go | 4 +- x-pack/elastic-agent/pkg/agent/cmd/run.go | 93 +- .../pkg/agent/control/control_test.go | 8 +- .../pkg/agent/control/server/server.go | 13 +- .../pkg/agent/operation/common_test.go | 5 +- .../pkg/agent/operation/monitoring_test.go | 4 +- .../pkg/agent/operation/operator.go | 13 +- .../pkg/agent/storage/store/state_store.go | 5 +- .../artifact/download/composed/downloader.go | 3 + .../pkg/artifact/download/fs/downloader.go | 7 +- .../pkg/basecmd/version/cmd_test.go | 7 +- .../pkg/core/monitoring/config/config.go | 25 + .../pkg/core/monitoring/config/config_test.go | 66 + .../pkg/core/monitoring/server/server.go | 17 +- .../elastic-agent/pkg/core/server/config.go | 6 +- .../pkg/core/server/config_test.go | 2 +- .../elastic-agent/pkg/core/server/server.go | 16 +- .../pkg/core/server/server_test.go | 4 +- x-pack/elastic-agent/pkg/fleetapi/ack_cmd.go | 38 +- .../pkg/fleetapi/acker/fleet/fleet_acker.go | 24 +- .../pkg/fleetapi/acker/lazy/lazy_acker.go | 25 +- .../pkg/fleetapi/client/client.go | 4 +- x-pack/elastic-agent/pkg/remote/client.go | 3 + 50 files changed, 1669 insertions(+), 216 deletions(-) create mode 100644 x-pack/elastic-agent/pkg/core/monitoring/config/config_test.go diff --git a/NOTICE.txt b/NOTICE.txt index 75163cd38c41..1adcddab37dd 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -15483,11 +15483,433 @@ Contents of probable licence file $GOMODCACHE/github.com/xdg/scram@v1.0.3/LICENS -------------------------------------------------------------------------------- Dependency : go.elastic.co/apm -Version: v1.11.0 +Version: v1.14.0 +Licence type (autodetected): Apache-2.0 +-------------------------------------------------------------------------------- + +Contents of probable licence file $GOMODCACHE/go.elastic.co/apm@v1.14.0/LICENSE: + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2018 Elasticsearch BV + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +-------------------------------------------------------------------------------- +Dependency : go.elastic.co/apm/module/apmelasticsearch +Version: v1.7.2 +Licence type (autodetected): Apache-2.0 +-------------------------------------------------------------------------------- + +Contents of probable licence file $GOMODCACHE/go.elastic.co/apm/module/apmelasticsearch@v1.7.2/LICENSE: + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2018 Elasticsearch BV + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +-------------------------------------------------------------------------------- +Dependency : go.elastic.co/apm/module/apmgorilla +Version: v1.14.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.elastic.co/apm@v1.11.0/LICENSE: +Contents of probable licence file $GOMODCACHE/go.elastic.co/apm/module/apmgorilla@v1.14.0/LICENSE: Apache License Version 2.0, January 2004 @@ -15693,12 +16115,12 @@ Contents of probable licence file $GOMODCACHE/go.elastic.co/apm@v1.11.0/LICENSE: -------------------------------------------------------------------------------- -Dependency : go.elastic.co/apm/module/apmelasticsearch -Version: v1.7.2 +Dependency : go.elastic.co/apm/module/apmgrpc +Version: v1.14.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.elastic.co/apm/module/apmelasticsearch@v1.7.2/LICENSE: +Contents of probable licence file $GOMODCACHE/go.elastic.co/apm/module/apmgrpc@v1.14.0/LICENSE: Apache License Version 2.0, January 2004 @@ -15905,11 +16327,11 @@ Contents of probable licence file $GOMODCACHE/go.elastic.co/apm/module/apmelasti -------------------------------------------------------------------------------- Dependency : go.elastic.co/apm/module/apmhttp -Version: v1.7.2 +Version: v1.14.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/go.elastic.co/apm/module/apmhttp@v1.7.2/LICENSE: +Contents of probable licence file $GOMODCACHE/go.elastic.co/apm/module/apmhttp@v1.14.0/LICENSE: Apache License Version 2.0, January 2004 @@ -23215,37 +23637,6 @@ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------------------------------- -Dependency : github.com/cucumber/godog -Version: v0.8.1 -Licence type (autodetected): MIT --------------------------------------------------------------------------------- - -Contents of probable licence file $GOMODCACHE/github.com/cucumber/godog@v0.8.1/LICENSE: - -The MIT License (MIT) - -Copyright (c) SmartBear - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - - -------------------------------------------------------------------------------- Dependency : github.com/cyphar/filepath-securejoin Version: v0.2.3 @@ -27061,37 +27452,247 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --------------------------------------------------------------------------------- -Dependency : github.com/gorilla/websocket -Version: v1.4.2 -Licence type (autodetected): BSD-2-Clause --------------------------------------------------------------------------------- +-------------------------------------------------------------------------------- +Dependency : github.com/gorilla/websocket +Version: v1.4.2 +Licence type (autodetected): BSD-2-Clause +-------------------------------------------------------------------------------- + +Contents of probable licence file $GOMODCACHE/github.com/gorilla/websocket@v1.4.2/LICENSE: + +Copyright (c) 2013 The Gorilla WebSocket Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +-------------------------------------------------------------------------------- +Dependency : github.com/grpc-ecosystem/go-grpc-middleware +Version: v1.0.1-0.20190118093823-f849b5445de4 +Licence type (autodetected): Apache-2.0 +-------------------------------------------------------------------------------- + +Contents of probable licence file $GOMODCACHE/github.com/grpc-ecosystem/go-grpc-middleware@v1.0.1-0.20190118093823-f849b5445de4/LICENSE: + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. -Contents of probable licence file $GOMODCACHE/github.com/gorilla/websocket@v1.4.2/LICENSE: + END OF TERMS AND CONDITIONS -Copyright (c) 2013 The Gorilla WebSocket Authors. All rights reserved. + APPENDIX: How to apply the Apache License to your work. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. + Copyright [yyyy] [name of copyright owner] - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. -------------------------------------------------------------------------------- Dependency : github.com/hashicorp/cronexpr @@ -29221,27 +29822,238 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --------------------------------------------------------------------------------- -Dependency : github.com/inconshreveable/mousetrap -Version: v1.0.0 -Licence type (autodetected): Apache-2.0 --------------------------------------------------------------------------------- +-------------------------------------------------------------------------------- +Dependency : github.com/inconshreveable/mousetrap +Version: v1.0.0 +Licence type (autodetected): Apache-2.0 +-------------------------------------------------------------------------------- + +Contents of probable licence file $GOMODCACHE/github.com/inconshreveable/mousetrap@v1.0.0/LICENSE: + +Copyright 2014 Alan Shreve + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + + +-------------------------------------------------------------------------------- +Dependency : github.com/jcchavezs/porto +Version: v0.1.0 +Licence type (autodetected): Apache-2.0 +-------------------------------------------------------------------------------- + +Contents of probable licence file $GOMODCACHE/github.com/jcchavezs/porto@v0.1.0/LICENSE: + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS -Contents of probable licence file $GOMODCACHE/github.com/inconshreveable/mousetrap@v1.0.0/LICENSE: + APPENDIX: How to apply the Apache License to your work. -Copyright 2014 Alan Shreve + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at + Copyright [yyyy] [name of copyright owner] - http://www.apache.org/licenses/LICENSE-2.0 + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. -------------------------------------------------------------------------------- @@ -34842,6 +35654,218 @@ Contents of probable licence file $GOMODCACHE/google.golang.org/appengine@v1.6.7 limitations under the License. +-------------------------------------------------------------------------------- +Dependency : google.golang.org/grpc/examples +Version: v0.0.0-20211115174500-b2317c762757 +Licence type (autodetected): Apache-2.0 +-------------------------------------------------------------------------------- + +Contents of probable licence file $GOMODCACHE/google.golang.org/grpc/examples@v0.0.0-20211115174500-b2317c762757/LICENSE: + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + -------------------------------------------------------------------------------- Dependency : gopkg.in/check.v1 Version: v1.0.0-20201130134442-10cb98267c6c diff --git a/go.mod b/go.mod index 1603cbf798f4..31d84ac9fa0d 100644 --- a/go.mod +++ b/go.mod @@ -153,9 +153,11 @@ require ( github.com/vmware/govmomi v0.0.0-20170802214208-2cad15190b41 github.com/xdg/scram v1.0.3 github.com/yuin/gopher-lua v0.0.0-20170403160031-b402f3114ec7 // indirect - go.elastic.co/apm v1.11.0 + go.elastic.co/apm v1.14.0 go.elastic.co/apm/module/apmelasticsearch v1.7.2 - go.elastic.co/apm/module/apmhttp v1.7.2 + go.elastic.co/apm/module/apmgorilla v1.14.0 + go.elastic.co/apm/module/apmgrpc v1.14.0 + go.elastic.co/apm/module/apmhttp v1.14.0 go.elastic.co/ecszap v0.3.0 go.elastic.co/go-licence-detector v0.4.0 go.etcd.io/bbolt v1.3.6 @@ -240,6 +242,7 @@ require ( github.com/hashicorp/go-version v1.2.0 // indirect github.com/imdario/mergo v0.3.12 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect + github.com/jcchavezs/porto v0.1.0 // indirect github.com/jcmturner/aescts/v2 v2.0.0 // indirect github.com/jcmturner/dnsutils/v2 v2.0.0 // indirect github.com/jcmturner/gofork v1.0.0 // indirect @@ -272,6 +275,7 @@ require ( golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect google.golang.org/appengine v1.6.7 // indirect + google.golang.org/grpc/examples v0.0.0-20211115174500-b2317c762757 // indirect gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect k8s.io/klog/v2 v2.30.0 // indirect k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65 // indirect diff --git a/go.sum b/go.sum index ad1e540577f4..72cd2a70666d 100644 --- a/go.sum +++ b/go.sum @@ -429,7 +429,6 @@ github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7Do github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw= github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/cucumber/godog v0.8.1 h1:lVb+X41I4YDreE+ibZ50bdXmySxgRviYFgKY6Aw4XE8= github.com/cucumber/godog v0.8.1/go.mod h1:vSh3r/lM+psC1BPXvdkSEuNjmXfpVqrMGYAElF6hxnA= github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= github.com/cyphar/filepath-securejoin v0.2.3 h1:YX6ebbZCZP7VkM3scTTokDgBL2TY741X51MTk3ycuNI= @@ -521,6 +520,7 @@ github.com/elastic/go-concert v0.2.0 h1:GAQrhRVXprnNjtvTP9pWJ1d4ToEA4cU5ci7TwTa2 github.com/elastic/go-concert v0.2.0/go.mod h1:HWjpO3IAEJUxOeaJOWXWEp7imKd27foxz9V5vegC/38= github.com/elastic/go-libaudit/v2 v2.2.0 h1:TY3FDpG4Zr9Qnv6KYW6olYr/U+nfu0rD2QAbv75VxMQ= github.com/elastic/go-libaudit/v2 v2.2.0/go.mod h1:MM/l/4xV7ilcl+cIblL8Zn448J7RZaDwgNLE4gNKYPg= +github.com/elastic/go-licenser v0.3.1/go.mod h1:D8eNQk70FOCVBl3smCGQt/lv7meBeQno2eI1S5apiHQ= github.com/elastic/go-licenser v0.4.0 h1:jLq6A5SilDS/Iz1ABRkO6BHy91B9jBora8FwGRsDqUI= github.com/elastic/go-licenser v0.4.0/go.mod h1:V56wHMpmdURfibNBggaSBfqgPxyT1Tldns1i87iTEvU= github.com/elastic/go-lookslike v0.3.0 h1:HDI/DQ65V85ZqM7D/sbxcK2wFFnh3+7iFvBk2v2FTHs= @@ -914,6 +914,7 @@ github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0U github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4 h1:z53tR0945TRRQO/fLEVPI6SMv7ZflF0TEaTAoU7tOzg= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= @@ -1019,6 +1020,8 @@ github.com/influxdata/usage-client v0.0.0-20160829180054-6d3895376368/go.mod h1: github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA= github.com/jarcoal/httpmock v1.0.4 h1:jp+dy/+nonJE4g4xbVtl9QdrUNbn6/3hDT5R4nDIZnA= github.com/jarcoal/httpmock v1.0.4/go.mod h1:ATjnClrvW/3tijVmpL/va5Z3aAyGvqU3gCT8nX0Txik= +github.com/jcchavezs/porto v0.1.0 h1:Xmxxn25zQMmgE7/yHYmh19KcItG81hIwfbEEFnd6w/Q= +github.com/jcchavezs/porto v0.1.0/go.mod h1:fESH0gzDHiutHRdX2hv27ojnOVFco37hg1W6E9EZF4A= github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8= github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs= github.com/jcmturner/dnsutils/v2 v2.0.0 h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8c/iPbo= @@ -1591,12 +1594,17 @@ github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA= github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg= go.elastic.co/apm v1.7.2/go.mod h1:tCw6CkOJgkWnzEthFN9HUP1uL3Gjc/Ur6m7gRPLaoH0= -go.elastic.co/apm v1.11.0 h1:uJyt6nCW9880sZhfl1tB//Jy/5TadNoAd8edRUtgb3w= -go.elastic.co/apm v1.11.0/go.mod h1:qoOSi09pnzJDh5fKnfY7bPmQgl8yl2tULdOu03xhui0= +go.elastic.co/apm v1.14.0 h1:9yilcTbWpqhfyunUj6/SDpZbR4FOVB50xQgODe0TW/0= +go.elastic.co/apm v1.14.0/go.mod h1:dylGv2HKR0tiCV+wliJz1KHtDyuD8SPe69oV7VyK6WY= go.elastic.co/apm/module/apmelasticsearch v1.7.2 h1:5STGHLZLSeAzxordMc+dFVKiyVtMmxADOV+TgRaXXJg= go.elastic.co/apm/module/apmelasticsearch v1.7.2/go.mod h1:ZyNFuyWdt42GBZkz0SogoLzDBrBGj4orxpiUuxYeYq8= -go.elastic.co/apm/module/apmhttp v1.7.2 h1:2mRh7SwBuEVLmJlX+hsMdcSg9xaielCLElaPn/+i34w= +go.elastic.co/apm/module/apmgorilla v1.14.0 h1:espCHSZ3ibkrffR6KLua+0jMeBSgO/087U9BZ46Cyv8= +go.elastic.co/apm/module/apmgorilla v1.14.0/go.mod h1:+cDGiyPXN3EvTxoh7zcWOL1/Yw6zKhNkUU0a0OGyXsg= +go.elastic.co/apm/module/apmgrpc v1.14.0 h1:sQA5XnxdKpjzKlMOJD1AKuMEsQh1CSdzJ21iJhZVNgw= +go.elastic.co/apm/module/apmgrpc v1.14.0/go.mod h1:rfw0Kw9yhui/O+rap4gDme0Pj2jGpTdN4iSWK2HM6+0= go.elastic.co/apm/module/apmhttp v1.7.2/go.mod h1:sTFWiWejnhSdZv6+dMgxGec2Nxe/ZKfHfz/xtRM+cRY= +go.elastic.co/apm/module/apmhttp v1.14.0 h1:uDSIPr1BJOt1A/T5J9Beq9VtMtQHqOdqQUXCPRQF4C4= +go.elastic.co/apm/module/apmhttp v1.14.0/go.mod h1:PY8hyV0X3eKqXYYoN0pyu1pWcvFCwGmh5eUFuS39Zmo= go.elastic.co/ecszap v0.3.0 h1:Zo/Y4sJLqbWDlqCHI4F4Lzeg0Fs4+n5ldVis4h9xV8w= go.elastic.co/ecszap v0.3.0/go.mod h1:HTUi+QRmr3EuZMqxPX+5fyOdMNfUu5iPebgfhgsTJYQ= go.elastic.co/fastjson v1.0.0/go.mod h1:PmeUOMMtLHQr9ZS9J9owrAVg0FkaZDRZJEFTTGHtchs= @@ -2163,6 +2171,7 @@ google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEY google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200806141610-86f49bd18e98/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= @@ -2234,6 +2243,8 @@ google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9K google.golang.org/grpc v1.41.0 h1:f+PlOh7QV4iIJkPrx5NQ7qaNGFQ3OTse67yaDHfju4E= google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= +google.golang.org/grpc/examples v0.0.0-20211115174500-b2317c762757 h1:d0UA5meuQRj/XhiC4CagMU1V3oZxYV+V9Nw2855gOqA= +google.golang.org/grpc/examples v0.0.0-20211115174500-b2317c762757/go.mod h1:gID3PKrg7pWKntu9Ss6zTLJ0ttC0X9IHgREOCZwbCVU= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/x-pack/elastic-agent/pkg/agent/application/application.go b/x-pack/elastic-agent/pkg/agent/application/application.go index d0de160340de..862fed5aa915 100644 --- a/x-pack/elastic-agent/pkg/agent/application/application.go +++ b/x-pack/elastic-agent/pkg/agent/application/application.go @@ -8,6 +8,8 @@ import ( "context" "fmt" + "go.elastic.co/apm" + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/errors" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/storage" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/core/status" @@ -39,7 +41,14 @@ type upgraderControl interface { } // New creates a new Agent and bootstrap the required subsystem. -func New(log *logger.Logger, reexec reexecManager, statusCtrl status.Controller, uc upgraderControl, agentInfo *info.AgentInfo) (Application, error) { +func New( + log *logger.Logger, + reexec reexecManager, + statusCtrl status.Controller, + uc upgraderControl, + agentInfo *info.AgentInfo, + tracer *apm.Tracer, +) (Application, error) { // Load configuration from disk to understand in which mode of operation // we must start the elastic-agent, the mode of operation cannot be changed without restarting the // elastic-agent. @@ -53,7 +62,7 @@ func New(log *logger.Logger, reexec reexecManager, statusCtrl status.Controller, return nil, err } - return createApplication(log, pathConfigFile, rawConfig, reexec, statusCtrl, uc, agentInfo) + return createApplication(log, pathConfigFile, rawConfig, reexec, statusCtrl, uc, agentInfo, tracer) } func createApplication( @@ -64,6 +73,7 @@ func createApplication( statusCtrl status.Controller, uc upgraderControl, agentInfo *info.AgentInfo, + tracer *apm.Tracer, ) (Application, error) { log.Info("Detecting execution mode") ctx := context.Background() @@ -74,7 +84,7 @@ func createApplication( if configuration.IsStandalone(cfg.Fleet) { log.Info("Agent is managed locally") - return newLocal(ctx, log, paths.ConfigFile(), rawConfig, reexec, statusCtrl, uc, agentInfo) + return newLocal(ctx, log, paths.ConfigFile(), rawConfig, reexec, statusCtrl, uc, agentInfo, tracer) } // not in standalone; both modes require reading the fleet.yml configuration file @@ -86,11 +96,11 @@ func createApplication( if configuration.IsFleetServerBootstrap(cfg.Fleet) { log.Info("Agent is in Fleet Server bootstrap mode") - return newFleetServerBootstrap(ctx, log, pathConfigFile, rawConfig, statusCtrl, agentInfo) + return newFleetServerBootstrap(ctx, log, pathConfigFile, rawConfig, statusCtrl, agentInfo, tracer) } log.Info("Agent is managed by Fleet") - return newManaged(ctx, log, store, cfg, rawConfig, reexec, statusCtrl, agentInfo) + return newManaged(ctx, log, store, cfg, rawConfig, reexec, statusCtrl, agentInfo, tracer) } func mergeFleetConfig(rawConfig *config.Config) (storage.Store, *configuration.Configuration, error) { diff --git a/x-pack/elastic-agent/pkg/agent/application/fleet_server_bootstrap.go b/x-pack/elastic-agent/pkg/agent/application/fleet_server_bootstrap.go index df4d93c3c43f..89cb816fec93 100644 --- a/x-pack/elastic-agent/pkg/agent/application/fleet_server_bootstrap.go +++ b/x-pack/elastic-agent/pkg/agent/application/fleet_server_bootstrap.go @@ -7,6 +7,8 @@ package application import ( "context" + "go.elastic.co/apm" + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/program" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/transpiler" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/sorted" @@ -51,6 +53,7 @@ func newFleetServerBootstrap( rawConfig *config.Config, statusCtrl status.Controller, agentInfo *info.AgentInfo, + tracer *apm.Tracer, ) (*FleetServerBootstrap, error) { cfg, err := configuration.NewFromConfig(rawConfig) if err != nil { @@ -79,7 +82,7 @@ func newFleetServerBootstrap( } bootstrapApp.bgContext, bootstrapApp.cancelCtxFn = context.WithCancel(ctx) - bootstrapApp.srv, err = server.NewFromConfig(log, cfg.Settings.GRPC, &operation.ApplicationStatusHandler{}) + bootstrapApp.srv, err = server.NewFromConfig(log, cfg.Settings.GRPC, &operation.ApplicationStatusHandler{}, tracer) if err != nil { return nil, errors.New(err, "initialize GRPC listener") } @@ -166,20 +169,22 @@ func bootstrapEmitter(ctx context.Context, log *logger.Logger, agentInfo transpi case c = <-ch: } - err := emit(log, agentInfo, router, modifiers, c) + err := emit(ctx, log, agentInfo, router, modifiers, c) if err != nil { log.Error(err) } } }() - return func(c *config.Config) error { + return func(ctx context.Context, c *config.Config) error { + span, _ := apm.StartSpan(ctx, "emit", "app.internal") + defer span.End() ch <- c return nil }, nil } -func emit(log *logger.Logger, agentInfo transpiler.AgentInfo, router pipeline.Router, modifiers *pipeline.ConfigModifiers, c *config.Config) error { +func emit(ctx context.Context, log *logger.Logger, agentInfo transpiler.AgentInfo, router pipeline.Router, modifiers *pipeline.ConfigModifiers, c *config.Config) error { if err := info.InjectAgentConfig(c); err != nil { return err } @@ -218,7 +223,7 @@ func emit(log *logger.Logger, agentInfo transpiler.AgentInfo, router pipeline.Ro return errors.New("bootstrap configuration is incorrect causing fleet-server to not be started") } - return router.Route(ast.HashStr(), map[pipeline.RoutingKey][]program.Program{ + return router.Route(ctx, ast.HashStr(), map[pipeline.RoutingKey][]program.Program{ pipeline.DefaultRK: { { Spec: spec, diff --git a/x-pack/elastic-agent/pkg/agent/application/gateway/fleet/fleet_gateway.go b/x-pack/elastic-agent/pkg/agent/application/gateway/fleet/fleet_gateway.go index fd835ee95f48..754c5315a4d9 100644 --- a/x-pack/elastic-agent/pkg/agent/application/gateway/fleet/fleet_gateway.go +++ b/x-pack/elastic-agent/pkg/agent/application/gateway/fleet/fleet_gateway.go @@ -176,7 +176,7 @@ func (f *fleetGateway) worker() { } var errMsg string - if err := f.dispatcher.Dispatch(f.acker, actions...); err != nil { + if err := f.dispatcher.Dispatch(context.Background(), f.acker, actions...); err != nil { errMsg = fmt.Sprintf("failed to dispatch actions, error: %s", err) f.log.Error(errMsg) f.statusReporter.Update(state.Failed, errMsg, nil) diff --git a/x-pack/elastic-agent/pkg/agent/application/gateway/fleet/fleet_gateway_test.go b/x-pack/elastic-agent/pkg/agent/application/gateway/fleet/fleet_gateway_test.go index eba95ad778c7..14ee33053aa5 100644 --- a/x-pack/elastic-agent/pkg/agent/application/gateway/fleet/fleet_gateway_test.go +++ b/x-pack/elastic-agent/pkg/agent/application/gateway/fleet/fleet_gateway_test.go @@ -78,7 +78,7 @@ type testingDispatcher struct { received chan struct{} } -func (t *testingDispatcher) Dispatch(acker store.FleetAcker, actions ...fleetapi.Action) error { +func (t *testingDispatcher) Dispatch(_ context.Context, acker store.FleetAcker, actions ...fleetapi.Action) error { t.Lock() defer t.Unlock() defer func() { t.received <- struct{}{} }() diff --git a/x-pack/elastic-agent/pkg/agent/application/gateway/fleetserver/fleet_gateway_local.go b/x-pack/elastic-agent/pkg/agent/application/gateway/fleetserver/fleet_gateway_local.go index 47998116bb69..2b6f2e131d2b 100644 --- a/x-pack/elastic-agent/pkg/agent/application/gateway/fleetserver/fleet_gateway_local.go +++ b/x-pack/elastic-agent/pkg/agent/application/gateway/fleetserver/fleet_gateway_local.go @@ -76,7 +76,7 @@ func New( // Start starts the gateway. func (w *fleetServerWrapper) Start() error { - err := w.emitter(w.injectedCfg) + err := w.emitter(context.Background(), w.injectedCfg) if err != nil { return err } diff --git a/x-pack/elastic-agent/pkg/agent/application/local_mode.go b/x-pack/elastic-agent/pkg/agent/application/local_mode.go index 4da6304e1ccf..a29977f2e8d0 100644 --- a/x-pack/elastic-agent/pkg/agent/application/local_mode.go +++ b/x-pack/elastic-agent/pkg/agent/application/local_mode.go @@ -7,6 +7,8 @@ package application import ( "context" + "go.elastic.co/apm" + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/application/filters" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/application/info" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/application/paths" @@ -65,6 +67,7 @@ func newLocal( statusCtrl status.Controller, uc upgraderControl, agentInfo *info.AgentInfo, + tracer *apm.Tracer, ) (*Local, error) { caps, err := capabilities.Load(paths.AgentCapabilitiesPath(), log, statusCtrl) if err != nil { @@ -91,7 +94,7 @@ func newLocal( } localApplication.bgContext, localApplication.cancelCtxFn = context.WithCancel(ctx) - localApplication.srv, err = server.NewFromConfig(log, cfg.Settings.GRPC, &operation.ApplicationStatusHandler{}) + localApplication.srv, err = server.NewFromConfig(log, cfg.Settings.GRPC, &operation.ApplicationStatusHandler{}, tracer) if err != nil { return nil, errors.New(err, "initialize GRPC listener") } diff --git a/x-pack/elastic-agent/pkg/agent/application/managed_mode.go b/x-pack/elastic-agent/pkg/agent/application/managed_mode.go index 9ac281bb5d44..5f528735c1e0 100644 --- a/x-pack/elastic-agent/pkg/agent/application/managed_mode.go +++ b/x-pack/elastic-agent/pkg/agent/application/managed_mode.go @@ -8,6 +8,8 @@ import ( "context" "fmt" + "go.elastic.co/apm" + "github.com/elastic/go-sysinfo" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/application/filters" @@ -78,6 +80,7 @@ func newManaged( reexec reexecManager, statusCtrl status.Controller, agentInfo *info.AgentInfo, + tracer *apm.Tracer, ) (*Managed, error) { caps, err := capabilities.Load(paths.AgentCapabilitiesPath(), log, statusCtrl) if err != nil { @@ -105,7 +108,7 @@ func newManaged( } managedApplication.bgContext, managedApplication.cancelCtxFn = context.WithCancel(ctx) - managedApplication.srv, err = server.NewFromConfig(log, cfg.Settings.GRPC, &operation.ApplicationStatusHandler{}) + managedApplication.srv, err = server.NewFromConfig(log, cfg.Settings.GRPC, &operation.ApplicationStatusHandler{}, tracer) if err != nil { return nil, errors.New(err, "initialize GRPC listener", errors.TypeNetwork) } @@ -155,6 +158,7 @@ func newManaged( if err != nil { return nil, err } + // Client has been instrumented with apm acker, err := fleet.NewAcker(log, agentInfo, client) if err != nil { return nil, err @@ -244,7 +248,7 @@ func newManaged( // TODO(ph) We will need an improvement on fleet, if there is an error while dispatching a // persisted action on disk we should be able to ask Fleet to get the latest configuration. // But at the moment this is not possible because the policy change was acked. - if err := store.ReplayActions(log, actionDispatcher, actionAcker, actions...); err != nil { + if err := store.ReplayActions(ctx, log, actionDispatcher, actionAcker, actions...); err != nil { log.Errorf("could not recover state, error %+v, skipping...", err) } stateRestored = true diff --git a/x-pack/elastic-agent/pkg/agent/application/managed_mode_test.go b/x-pack/elastic-agent/pkg/agent/application/managed_mode_test.go index 7d52d69d4b85..26a8251f07be 100644 --- a/x-pack/elastic-agent/pkg/agent/application/managed_mode_test.go +++ b/x-pack/elastic-agent/pkg/agent/application/managed_mode_test.go @@ -67,7 +67,7 @@ func TestManagedModeRouting(t *testing.T) { actions, err := testActions() require.NoError(t, err) - err = actionDispatcher.Dispatch(noopacker.NewAcker(), actions...) + err = actionDispatcher.Dispatch(context.Background(), noopacker.NewAcker(), actions...) require.NoError(t, err) // has 1 config request for fb, mb and monitoring? @@ -101,7 +101,7 @@ func newMockStreamStore() *mockStreamStore { } } -func (m *mockStreamStore) Execute(cr configrequest.Request) error { +func (m *mockStreamStore) Execute(_ context.Context, cr configrequest.Request) error { m.store = append(m.store, cr) return nil } diff --git a/x-pack/elastic-agent/pkg/agent/application/once.go b/x-pack/elastic-agent/pkg/agent/application/once.go index 39d53512a243..64ee34e25902 100644 --- a/x-pack/elastic-agent/pkg/agent/application/once.go +++ b/x-pack/elastic-agent/pkg/agent/application/once.go @@ -5,6 +5,8 @@ package application import ( + "context" + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/application/pipeline" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/errors" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/config" @@ -31,18 +33,18 @@ func (o *once) Start() error { return ErrNoConfiguration } - return readfiles(files, o.emitter) + return readfiles(context.Background(), files, o.emitter) } func (o *once) Stop() error { return nil } -func readfiles(files []string, emitter pipeline.EmitterFunc) error { +func readfiles(ctx context.Context, files []string, emitter pipeline.EmitterFunc) error { c, err := config.LoadFiles(files...) if err != nil { return errors.New(err, "could not load or merge configuration", errors.TypeConfig) } - return emitter(c) + return emitter(ctx, c) } diff --git a/x-pack/elastic-agent/pkg/agent/application/periodic.go b/x-pack/elastic-agent/pkg/agent/application/periodic.go index 272169c6de48..f79c09b6e681 100644 --- a/x-pack/elastic-agent/pkg/agent/application/periodic.go +++ b/x-pack/elastic-agent/pkg/agent/application/periodic.go @@ -5,6 +5,7 @@ package application import ( + "context" "strings" "time" @@ -89,7 +90,7 @@ func (p *periodic) work() error { p.log.Debugf("Unchanged %d files: %s", len(s.Unchanged), strings.Join(s.Updated, ", ")) } - err := readfiles(files, p.emitter) + err := readfiles(context.Background(), files, p.emitter) if err != nil { // assume something when really wrong and invalidate any cache // so we get a full new config on next tick. diff --git a/x-pack/elastic-agent/pkg/agent/application/pipeline/actions/handlers/handler_action_policy_change.go b/x-pack/elastic-agent/pkg/agent/application/pipeline/actions/handlers/handler_action_policy_change.go index e00ccfc844ba..6e72a45d45f5 100644 --- a/x-pack/elastic-agent/pkg/agent/application/pipeline/actions/handlers/handler_action_policy_change.go +++ b/x-pack/elastic-agent/pkg/agent/application/pipeline/actions/handlers/handler_action_policy_change.go @@ -89,7 +89,7 @@ func (h *PolicyChange) Handle(ctx context.Context, a fleetapi.Action, acker stor if err != nil { return err } - if err := h.emitter(c); err != nil { + if err := h.emitter(ctx, c); err != nil { return err } diff --git a/x-pack/elastic-agent/pkg/agent/application/pipeline/actions/handlers/handler_action_policy_change_test.go b/x-pack/elastic-agent/pkg/agent/application/pipeline/actions/handlers/handler_action_policy_change_test.go index 1c4c37509398..98b7e21fc653 100644 --- a/x-pack/elastic-agent/pkg/agent/application/pipeline/actions/handlers/handler_action_policy_change_test.go +++ b/x-pack/elastic-agent/pkg/agent/application/pipeline/actions/handlers/handler_action_policy_change_test.go @@ -28,7 +28,7 @@ type mockEmitter struct { policy *config.Config } -func (m *mockEmitter) Emitter(policy *config.Config) error { +func (m *mockEmitter) Emitter(_ context.Context, policy *config.Config) error { m.policy = policy return m.err } diff --git a/x-pack/elastic-agent/pkg/agent/application/pipeline/actions/handlers/handler_action_unenroll.go b/x-pack/elastic-agent/pkg/agent/application/pipeline/actions/handlers/handler_action_unenroll.go index aeecf865b0fe..a2649bdf41a9 100644 --- a/x-pack/elastic-agent/pkg/agent/application/pipeline/actions/handlers/handler_action_unenroll.go +++ b/x-pack/elastic-agent/pkg/agent/application/pipeline/actions/handlers/handler_action_unenroll.go @@ -60,7 +60,7 @@ func (h *Unenroll) Handle(ctx context.Context, a fleetapi.Action, acker store.Fl // Providing empty map will close all pipelines noPrograms := make(map[pipeline.RoutingKey][]program.Program) - h.dispatcher.Route(a.ID(), noPrograms) + h.dispatcher.Route(ctx, a.ID(), noPrograms) if !action.IsDetected { // ACK only events comming from fleet diff --git a/x-pack/elastic-agent/pkg/agent/application/pipeline/dispatcher/dispatcher.go b/x-pack/elastic-agent/pkg/agent/application/pipeline/dispatcher/dispatcher.go index 7a1ea23a42dc..e4e98523b27a 100644 --- a/x-pack/elastic-agent/pkg/agent/application/pipeline/dispatcher/dispatcher.go +++ b/x-pack/elastic-agent/pkg/agent/application/pipeline/dispatcher/dispatcher.go @@ -10,6 +10,8 @@ import ( "reflect" "strings" + "go.elastic.co/apm" + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/application/pipeline/actions" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/errors" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/storage/store" @@ -74,7 +76,15 @@ func (ad *ActionDispatcher) key(a fleetapi.Action) string { } // Dispatch dispatches an action using pre-registered set of handlers. -func (ad *ActionDispatcher) Dispatch(acker store.FleetAcker, actions ...fleetapi.Action) error { +func (ad *ActionDispatcher) Dispatch(ctx context.Context, acker store.FleetAcker, actions ...fleetapi.Action) (err error) { + span, ctx := apm.StartSpan(ctx, "dispatch", "app.internal") + defer func() { + if err != nil { + apm.CaptureError(ctx, err).Send() + } + span.End() + }() + if len(actions) == 0 { ad.log.Debug("No action to dispatch") return nil @@ -87,18 +97,19 @@ func (ad *ActionDispatcher) Dispatch(acker store.FleetAcker, actions ...fleetapi ) for _, action := range actions { - if err := ad.ctx.Err(); err != nil { + if err = ad.ctx.Err(); err != nil { return err } - if err := ad.dispatchAction(action, acker); err != nil { + if err = ad.dispatchAction(action, acker); err != nil { ad.log.Debugf("Failed to dispatch action '%+v', error: %+v", action, err) return err } ad.log.Debugf("Successfully dispatched action: '%+v'", action) } - return acker.Commit(ad.ctx) + err = acker.Commit(ctx) + return err } func (ad *ActionDispatcher) dispatchAction(a fleetapi.Action, acker store.FleetAcker) error { diff --git a/x-pack/elastic-agent/pkg/agent/application/pipeline/dispatcher/dispatcher_test.go b/x-pack/elastic-agent/pkg/agent/application/pipeline/dispatcher/dispatcher_test.go index 504778ad804a..7bba53feb59b 100644 --- a/x-pack/elastic-agent/pkg/agent/application/pipeline/dispatcher/dispatcher_test.go +++ b/x-pack/elastic-agent/pkg/agent/application/pipeline/dispatcher/dispatcher_test.go @@ -49,8 +49,9 @@ func TestActionDispatcher(t *testing.T) { ack := noopacker.NewAcker() t.Run("Success to dispatch multiples events", func(t *testing.T) { + ctx := context.Background() def := &mockHandler{} - d, err := New(context.Background(), nil, def) + d, err := New(ctx, nil, def) require.NoError(t, err) success1 := &mockHandler{} @@ -62,7 +63,7 @@ func TestActionDispatcher(t *testing.T) { action1 := &mockAction{} action2 := &mockActionOther{} - err = d.Dispatch(ack, action1, action2) + err = d.Dispatch(ctx, ack, action1, action2) require.NoError(t, err) @@ -78,11 +79,12 @@ func TestActionDispatcher(t *testing.T) { t.Run("Unknown action are caught by the unknown handler", func(t *testing.T) { def := &mockHandler{} - d, err := New(context.Background(), nil, def) + ctx := context.Background() + d, err := New(ctx, nil, def) require.NoError(t, err) action := &mockActionUnknown{} - err = d.Dispatch(ack, action) + err = d.Dispatch(ctx, ack, action) require.NoError(t, err) require.True(t, def.called) diff --git a/x-pack/elastic-agent/pkg/agent/application/pipeline/emitter/controller.go b/x-pack/elastic-agent/pkg/agent/application/pipeline/emitter/controller.go index 5ece0a1b1deb..d7ddaffedf53 100644 --- a/x-pack/elastic-agent/pkg/agent/application/pipeline/emitter/controller.go +++ b/x-pack/elastic-agent/pkg/agent/application/pipeline/emitter/controller.go @@ -5,8 +5,11 @@ package emitter import ( + "context" "sync" + "go.elastic.co/apm" + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/application/info" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/application/pipeline" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/errors" @@ -65,38 +68,51 @@ func NewController( } // Update applies config change and performes all steps necessary to apply it. -func (e *Controller) Update(c *config.Config) error { - if err := info.InjectAgentConfig(c); err != nil { - return err +func (e *Controller) Update(ctx context.Context, c *config.Config) (rErr error) { + span, ctx := apm.StartSpan(ctx, "update", "app.internal") + defer func() { + if rErr != nil { + apm.CaptureError(ctx, rErr).Send() + } + span.End() + }() + + if rErr = info.InjectAgentConfig(c); rErr != nil { + return } // perform and verify ast translation m, err := c.ToMapStr() if err != nil { - return errors.New(err, "could not create the AST from the configuration", errors.TypeConfig) + rErr = errors.New(err, "could not create the AST from the configuration", errors.TypeConfig) + return } rawAst, err := transpiler.NewAST(m) if err != nil { - return errors.New(err, "could not create the AST from the configuration", errors.TypeConfig) + rErr = errors.New(err, "could not create the AST from the configuration", errors.TypeConfig) + return } if e.caps != nil { var ok bool updatedAst, err := e.caps.Apply(rawAst) if err != nil { - return errors.New(err, "failed to apply capabilities") + rErr = errors.New(err, "failed to apply capabilities") + return } rawAst, ok = updatedAst.(*transpiler.AST) if !ok { - return errors.New("failed to transform object returned from capabilities to AST", errors.TypeConfig) + rErr = errors.New("failed to transform object returned from capabilities to AST", errors.TypeConfig) + return } } for _, filter := range e.modifiers.Filters { if err := filter(e.logger, rawAst); err != nil { - return errors.New(err, "failed to filter configuration", errors.TypeConfig) + rErr = errors.New(err, "failed to filter configuration", errors.TypeConfig) + return } } @@ -105,25 +121,41 @@ func (e *Controller) Update(c *config.Config) error { e.ast = rawAst e.lock.Unlock() - return e.update() + rErr = e.update(ctx) + return } // Set sets the transpiler vars for dynamic inputs resolution. -func (e *Controller) Set(vars []*transpiler.Vars) { +func (e *Controller) Set(ctx context.Context, vars []*transpiler.Vars) { + var err error + span, ctx := apm.StartSpan(ctx, "Set", "app.internal") + defer func() { + if err != nil { + apm.CaptureError(ctx, err).Send() + } + span.End() + }() e.lock.Lock() ast := e.ast e.vars = vars e.lock.Unlock() if ast != nil { - err := e.update() + err = e.update(ctx) if err != nil { e.logger.Errorf("Failed to render configuration with latest context from composable controller: %s", err) } } } -func (e *Controller) update() error { +func (e *Controller) update(ctx context.Context) (err error) { + span, ctx := apm.StartSpan(ctx, "update", "app.internal") + defer func() { + if err != nil { + apm.CaptureError(ctx, err).Send() + } + span.End() + }() // locking whole update because it can be called concurrently via Set and Update method e.updateLock.Lock() defer e.updateLock.Unlock() @@ -137,19 +169,21 @@ func (e *Controller) update() error { ast := rawAst.Clone() inputs, ok := transpiler.Lookup(ast, "inputs") if ok { - renderedInputs, err := transpiler.RenderInputs(inputs, varsArray) + var renderedInputs transpiler.Node + renderedInputs, err = transpiler.RenderInputs(inputs, varsArray) if err != nil { return err } err = transpiler.Insert(ast, renderedInputs, "inputs") if err != nil { - return errors.New(err, "inserting rendered inputs failed") + return err } } e.logger.Debug("Converting single configuration into specific programs configuration") - programsToRun, err := program.Programs(e.agentInfo, ast) + programsToRun := make(map[string][]program.Program) + programsToRun, err = program.Programs(e.agentInfo, ast) if err != nil { return err } @@ -164,10 +198,11 @@ func (e *Controller) update() error { } for _, r := range e.reloadables { - if err := r.Reload(cfg); err != nil { + if err = r.Reload(cfg); err != nil { return err } } - return e.router.Route(ast.HashStr(), programsToRun) + err = e.router.Route(ctx, ast.HashStr(), programsToRun) + return err } diff --git a/x-pack/elastic-agent/pkg/agent/application/pipeline/emitter/emitter.go b/x-pack/elastic-agent/pkg/agent/application/pipeline/emitter/emitter.go index 8b49bffea44f..f9e7453ce7c0 100644 --- a/x-pack/elastic-agent/pkg/agent/application/pipeline/emitter/emitter.go +++ b/x-pack/elastic-agent/pkg/agent/application/pipeline/emitter/emitter.go @@ -8,6 +8,8 @@ import ( "context" "strings" + "go.elastic.co/apm" + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/application/info" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/application/pipeline" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/errors" @@ -25,12 +27,20 @@ func New(ctx context.Context, log *logger.Logger, agentInfo *info.AgentInfo, con ctrl := NewController(log, agentInfo, controller, router, modifiers, caps, reloadables...) err := controller.Run(ctx, func(vars []*transpiler.Vars) { - ctrl.Set(vars) + ctrl.Set(ctx, vars) }) if err != nil { return nil, errors.New(err, "failed to start composable controller") } - return func(c *config.Config) error { - return ctrl.Update(c) + return func(ctx context.Context, c *config.Config) (err error) { + span, ctx := apm.StartSpan(ctx, "update", "app.internal") + defer func() { + if err != nil { + apm.CaptureError(ctx, err).Send() + } + span.End() + }() + err = ctrl.Update(ctx, c) + return err }, nil } diff --git a/x-pack/elastic-agent/pkg/agent/application/pipeline/pipeline.go b/x-pack/elastic-agent/pkg/agent/application/pipeline/pipeline.go index f2f02efb2585..1cc73dca5d8e 100644 --- a/x-pack/elastic-agent/pkg/agent/application/pipeline/pipeline.go +++ b/x-pack/elastic-agent/pkg/agent/application/pipeline/pipeline.go @@ -5,6 +5,8 @@ package pipeline import ( + "context" + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/application/info" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/configrequest" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/program" @@ -18,7 +20,7 @@ import ( // ConfigHandler is capable of handling configrequest. type ConfigHandler interface { - HandleConfig(configrequest.Request) error + HandleConfig(context.Context, configrequest.Request) error Close() error Shutdown() } @@ -32,7 +34,7 @@ type RoutingKey = string // Router is an interface routing programs to the corresponding stream. type Router interface { Routes() *sorted.Set - Route(id string, grpProg map[RoutingKey][]program.Program) error + Route(ctx context.Context, id string, grpProg map[RoutingKey][]program.Program) error Shutdown() } @@ -41,13 +43,13 @@ type StreamFunc func(*logger.Logger, RoutingKey) (Stream, error) // Stream is capable of executing configrequest change. type Stream interface { - Execute(configrequest.Request) error + Execute(context.Context, configrequest.Request) error Close() error Shutdown() } // EmitterFunc emits configuration for processing. -type EmitterFunc func(*config.Config) error +type EmitterFunc func(context.Context, *config.Config) error // DecoratorFunc is a func for decorating a retrieved configuration before processing. type DecoratorFunc = func(*info.AgentInfo, string, *transpiler.AST, []program.Program) ([]program.Program, error) @@ -63,5 +65,5 @@ type ConfigModifiers struct { // Dispatcher processes actions coming from fleet api. type Dispatcher interface { - Dispatch(acker store.FleetAcker, actions ...fleetapi.Action) error + Dispatch(context.Context, store.FleetAcker, ...fleetapi.Action) error } diff --git a/x-pack/elastic-agent/pkg/agent/application/pipeline/router/router.go b/x-pack/elastic-agent/pkg/agent/application/pipeline/router/router.go index bda4a7b7cde7..f8bd0f6e832a 100644 --- a/x-pack/elastic-agent/pkg/agent/application/pipeline/router/router.go +++ b/x-pack/elastic-agent/pkg/agent/application/pipeline/router/router.go @@ -5,6 +5,7 @@ package router import ( + "context" "fmt" "strings" "time" @@ -38,7 +39,7 @@ func (r *router) Routes() *sorted.Set { return r.routes } -func (r *router) Route(id string, grpProg map[pipeline.RoutingKey][]program.Program) error { +func (r *router) Route(ctx context.Context, id string, grpProg map[pipeline.RoutingKey][]program.Program) error { s := sorted.NewSet() // Make sure that starting and updating is always done in the same order. @@ -77,7 +78,7 @@ func (r *router) Route(id string, grpProg map[pipeline.RoutingKey][]program.Prog strings.Join(req.ProgramNames(), ", "), ) - err = p.(pipeline.Stream).Execute(req) + err = p.(pipeline.Stream).Execute(ctx, req) if err != nil { return err } diff --git a/x-pack/elastic-agent/pkg/agent/application/pipeline/router/router_test.go b/x-pack/elastic-agent/pkg/agent/application/pipeline/router/router_test.go index 421a0f4cc919..77e3be645743 100644 --- a/x-pack/elastic-agent/pkg/agent/application/pipeline/router/router_test.go +++ b/x-pack/elastic-agent/pkg/agent/application/pipeline/router/router_test.go @@ -5,6 +5,7 @@ package router import ( + "context" "testing" "github.com/stretchr/testify/require" @@ -45,12 +46,13 @@ type notifyFunc func(pipeline.RoutingKey, rOp, ...interface{}) func TestRouter(t *testing.T) { programs := []program.Program{program.Program{Spec: program.Supported[1]}} + ctx := context.Background() t.Run("create new and destroy unused stream", func(t *testing.T) { recorder := &recorder{} r, err := New(nil, recorder.factory) require.NoError(t, err) - r.Route("hello", map[pipeline.RoutingKey][]program.Program{ + r.Route(ctx, "hello", map[pipeline.RoutingKey][]program.Program{ pipeline.DefaultRK: programs, }) @@ -62,7 +64,7 @@ func TestRouter(t *testing.T) { recorder.reset() nk := "NEW_KEY" - r.Route("hello-2", map[pipeline.RoutingKey][]program.Program{ + r.Route(ctx, "hello-2", map[pipeline.RoutingKey][]program.Program{ nk: programs, }) @@ -80,7 +82,7 @@ func TestRouter(t *testing.T) { recorder := &recorder{} r, err := New(nil, recorder.factory) require.NoError(t, err) - r.Route("hello", map[pipeline.RoutingKey][]program.Program{ + r.Route(ctx, "hello", map[pipeline.RoutingKey][]program.Program{ pipeline.DefaultRK: programs, k1: programs, k2: programs, @@ -100,7 +102,7 @@ func TestRouter(t *testing.T) { recorder.reset() nk := "SECOND_DISPATCH" - r.Route("hello-2", map[pipeline.RoutingKey][]program.Program{ + r.Route(ctx, "hello-2", map[pipeline.RoutingKey][]program.Program{ nk: programs, }) @@ -118,7 +120,7 @@ func TestRouter(t *testing.T) { recorder := &recorder{} r, err := New(nil, recorder.factory) require.NoError(t, err) - r.Route("hello", map[pipeline.RoutingKey][]program.Program{ + r.Route(ctx, "hello", map[pipeline.RoutingKey][]program.Program{ pipeline.DefaultRK: programs, }) @@ -129,7 +131,7 @@ func TestRouter(t *testing.T) { recorder.reset() - r.Route("hello-2", map[pipeline.RoutingKey][]program.Program{ + r.Route(ctx, "hello-2", map[pipeline.RoutingKey][]program.Program{ pipeline.DefaultRK: programs, }) @@ -145,7 +147,7 @@ func TestRouter(t *testing.T) { recorder := &recorder{} r, err := New(nil, recorder.factory) require.NoError(t, err) - r.Route("hello", map[pipeline.RoutingKey][]program.Program{ + r.Route(ctx, "hello", map[pipeline.RoutingKey][]program.Program{ pipeline.DefaultRK: programs, k1: programs, k2: programs, @@ -162,7 +164,7 @@ func TestRouter(t *testing.T) { recorder.reset() - r.Route("hello-2", map[pipeline.RoutingKey][]program.Program{}) + r.Route(ctx, "hello-2", map[pipeline.RoutingKey][]program.Program{}) assertOps(t, []event{ e(k1, closeOp), @@ -201,7 +203,7 @@ func newMockStream(rk pipeline.RoutingKey, notify notifyFunc) *mockStream { } } -func (m *mockStream) Execute(req configrequest.Request) error { +func (m *mockStream) Execute(_ context.Context, req configrequest.Request) error { m.event(executeOp, req) return nil } diff --git a/x-pack/elastic-agent/pkg/agent/application/pipeline/stream/operator_stream.go b/x-pack/elastic-agent/pkg/agent/application/pipeline/stream/operator_stream.go index f56b1cfb3e9a..34ad4a6c0dc2 100644 --- a/x-pack/elastic-agent/pkg/agent/application/pipeline/stream/operator_stream.go +++ b/x-pack/elastic-agent/pkg/agent/application/pipeline/stream/operator_stream.go @@ -5,6 +5,10 @@ package stream import ( + "context" + + "go.elastic.co/apm" + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/application/pipeline" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/configrequest" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/program" @@ -44,8 +48,16 @@ func (b *operatorStream) Specs() map[string]program.Spec { return nil } -func (b *operatorStream) Execute(cfg configrequest.Request) error { - return b.configHandler.HandleConfig(cfg) +func (b *operatorStream) Execute(ctx context.Context, cfg configrequest.Request) (err error) { + span, ctx := apm.StartSpan(ctx, "route", "app.internal") + defer func() { + if err != nil { + apm.CaptureError(ctx, err).Send() + } + span.End() + }() + err = b.configHandler.HandleConfig(ctx, cfg) + return } func (b *operatorStream) Shutdown() { diff --git a/x-pack/elastic-agent/pkg/agent/application/upgrade/step_download.go b/x-pack/elastic-agent/pkg/agent/application/upgrade/step_download.go index 2a88b8bfb2ba..603a544cd01a 100644 --- a/x-pack/elastic-agent/pkg/agent/application/upgrade/step_download.go +++ b/x-pack/elastic-agent/pkg/agent/application/upgrade/step_download.go @@ -8,6 +8,8 @@ import ( "context" "strings" + "go.elastic.co/apm" + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/errors" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/artifact" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/artifact/download" @@ -20,7 +22,14 @@ import ( "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/release" ) -func (u *Upgrader) downloadArtifact(ctx context.Context, version, sourceURI string) (string, error) { +func (u *Upgrader) downloadArtifact(ctx context.Context, version, sourceURI string) (_ string, err error) { + span, ctx := apm.StartSpan(ctx, "downloadArtifact", "app.internal") + defer func() { + if err != nil { + apm.CaptureError(ctx, err).Send() + } + span.End() + }() // do not update source config settings := *u.settings if sourceURI != "" { diff --git a/x-pack/elastic-agent/pkg/agent/application/upgrade/upgrade.go b/x-pack/elastic-agent/pkg/agent/application/upgrade/upgrade.go index 915106ad0e35..b3ef19ad9123 100644 --- a/x-pack/elastic-agent/pkg/agent/application/upgrade/upgrade.go +++ b/x-pack/elastic-agent/pkg/agent/application/upgrade/upgrade.go @@ -13,6 +13,7 @@ import ( "strings" "github.com/otiai10/copy" + "go.elastic.co/apm" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/application/info" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/application/paths" @@ -107,12 +108,15 @@ func (u *Upgrader) Upgradeable() bool { // Upgrade upgrades running agent, function returns shutdown callback if some needs to be executed for cases when // reexec is called by caller. func (u *Upgrader) Upgrade(ctx context.Context, a Action, reexecNow bool) (_ reexec.ShutdownCallbackFn, err error) { + span, ctx := apm.StartSpan(ctx, "upgrade", "app.internal") + defer span.End() // report failed defer func() { if err != nil { if action := a.FleetAction(); action != nil { u.reportFailure(ctx, action, err) } + apm.CaptureError(ctx, err).Send() } }() diff --git a/x-pack/elastic-agent/pkg/agent/cmd/enroll_cmd.go b/x-pack/elastic-agent/pkg/agent/cmd/enroll_cmd.go index da6c2be9e5e3..0d749111467c 100644 --- a/x-pack/elastic-agent/pkg/agent/cmd/enroll_cmd.go +++ b/x-pack/elastic-agent/pkg/agent/cmd/enroll_cmd.go @@ -15,6 +15,7 @@ import ( "os/exec" "time" + "go.elastic.co/apm" "gopkg.in/yaml.v2" "github.com/elastic/beats/v7/libbeat/common/transport/httpcommon" @@ -184,8 +185,16 @@ func newEnrollCmdWithStore( func (c *enrollCmd) Execute(ctx context.Context, streams *cli.IOStreams) error { var err error defer c.stopAgent() // ensure its stopped no matter what + span, ctx := apm.StartSpan(ctx, "enroll", "app.internal") + defer func() { + if err != nil { + apm.CaptureError(ctx, err).Send() + } + span.End() + }() - persistentConfig, err := getPersistentConfig(c.configPath) + var persistentConfig map[string]interface{} + persistentConfig, err = getPersistentConfig(c.configPath) if err != nil { return err } @@ -195,7 +204,8 @@ func (c *enrollCmd) Execute(ctx context.Context, streams *cli.IOStreams) error { // Connection setup should disable proxies in that case. localFleetServer := c.options.FleetServer.ConnStr != "" if localFleetServer && !c.options.DelayEnroll { - token, err := c.fleetServerBootstrap(ctx, persistentConfig) + var token string + token, err = c.fleetServerBootstrap(ctx, persistentConfig) if err != nil { return err } @@ -206,10 +216,11 @@ func (c *enrollCmd) Execute(ctx context.Context, streams *cli.IOStreams) error { c.remoteConfig, err = c.options.remoteConfig() if err != nil { - return errors.New( + err = errors.New( err, "Error", errors.TypeConfig, errors.M(errors.MetaKeyURI, c.options.URL)) + return err } if localFleetServer { // Ensure that the agent does not use a proxy configuration @@ -219,28 +230,32 @@ func (c *enrollCmd) Execute(ctx context.Context, streams *cli.IOStreams) error { c.client, err = fleetclient.NewWithConfig(c.log, c.remoteConfig) if err != nil { - return errors.New( + err = errors.New( err, "Error", errors.TypeNetwork, errors.M(errors.MetaKeyURI, c.options.URL)) + return err } if c.options.DelayEnroll { if c.options.FleetServer.Host != "" { - return errors.New("--delay-enroll cannot be used with --fleet-server-es", errors.TypeConfig) + err = errors.New("--delay-enroll cannot be used with --fleet-server-es", errors.TypeConfig) + return err } return c.writeDelayEnroll(streams) } err = c.enrollWithBackoff(ctx, persistentConfig) if err != nil { - return errors.New(err, "fail to enroll") + err = errors.New(err, "fail to enroll") + return err } if c.options.FixPermissions { err = install.FixPermissions() if err != nil { - return errors.New(err, "failed to fix permissions") + err = errors.New(err, "failed to fix permissions") + return err } } diff --git a/x-pack/elastic-agent/pkg/agent/cmd/inspect.go b/x-pack/elastic-agent/pkg/agent/cmd/inspect.go index 56a8f97c131d..03db5837a1fa 100644 --- a/x-pack/elastic-agent/pkg/agent/cmd/inspect.go +++ b/x-pack/elastic-agent/pkg/agent/cmd/inspect.go @@ -295,7 +295,7 @@ func getProgramsFromConfig(log *logger.Logger, agentInfo *info.AgentInfo, cfg *c return nil, err } - if err := emit(cfg); err != nil { + if err := emit(ctx, cfg); err != nil { return nil, err } composableWaiter.Wait() @@ -310,7 +310,7 @@ func (r *inmemRouter) Routes() *sorted.Set { return nil } -func (r *inmemRouter) Route(id string, grpProg map[pipeline.RoutingKey][]program.Program) error { +func (r *inmemRouter) Route(_ context.Context, _ string, grpProg map[pipeline.RoutingKey][]program.Program) error { r.programs = grpProg return nil } diff --git a/x-pack/elastic-agent/pkg/agent/cmd/run.go b/x-pack/elastic-agent/pkg/agent/cmd/run.go index 7f10f9faa31d..4c199bd34a4a 100644 --- a/x-pack/elastic-agent/pkg/agent/cmd/run.go +++ b/x-pack/elastic-agent/pkg/agent/cmd/run.go @@ -8,12 +8,15 @@ import ( "context" "fmt" "io/ioutil" + "net/url" "os" "os/signal" "path/filepath" "syscall" "github.com/spf13/cobra" + "go.elastic.co/apm" + apmtransport "go.elastic.co/apm/transport" "gopkg.in/yaml.v2" "github.com/elastic/beats/v7/libbeat/api" @@ -44,6 +47,10 @@ const ( agentName = "elastic-agent" ) +func init() { + apm.DefaultTracer.Close() +} + type cfgOverrider func(cfg *configuration.Configuration) func newRunCommandWithArgs(_ []string, streams *cli.IOStreams) *cobra.Command { @@ -135,14 +142,25 @@ func run(streams *cli.IOStreams, override cfgOverrider) error { statusCtrl := status.NewController(logger) + tracer, err := initTracer(agentName, release.Version(), cfg.Settings.MonitoringConfig) + if err != nil { + return err + } + if tracer != nil { + defer func() { + tracer.Flush(nil) + tracer.Close() + }() + } + + control := server.New(logger.Named("control"), rex, statusCtrl, nil, tracer) // start the control listener - control := server.New(logger.Named("control"), rex, statusCtrl, nil) if err := control.Start(); err != nil { return err } defer control.Stop() - app, err := application.New(logger, rex, statusCtrl, control, agentInfo) + app, err := application.New(logger, rex, statusCtrl, control, agentInfo, tracer) if err != nil { return err } @@ -150,7 +168,7 @@ func run(streams *cli.IOStreams, override cfgOverrider) error { control.SetRouteFn(app.Routes) control.SetMonitoringCfg(cfg.Settings.MonitoringConfig) - serverStopFn, err := setupMetrics(agentInfo, logger, cfg.Settings.DownloadConfig.OS(), cfg.Settings.MonitoringConfig, app) + serverStopFn, err := setupMetrics(agentInfo, logger, cfg.Settings.DownloadConfig.OS(), cfg.Settings.MonitoringConfig, app, tracer) if err != nil { return err } @@ -296,7 +314,14 @@ func defaultLogLevel(cfg *configuration.Configuration) string { return defaultLogLevel } -func setupMetrics(agentInfo *info.AgentInfo, logger *logger.Logger, operatingSystem string, cfg *monitoringCfg.MonitoringConfig, app application.Application) (func() error, error) { +func setupMetrics( + agentInfo *info.AgentInfo, + logger *logger.Logger, + operatingSystem string, + cfg *monitoringCfg.MonitoringConfig, + app application.Application, + tracer *apm.Tracer, +) (func() error, error) { // use libbeat to setup metrics if err := metrics.SetupMetrics(agentName); err != nil { return nil, err @@ -308,7 +333,7 @@ func setupMetrics(agentInfo *info.AgentInfo, logger *logger.Logger, operatingSys Host: beats.AgentMonitoringEndpoint(operatingSystem, cfg.HTTP), } - s, err := monitoringServer.New(logger, endpointConfig, monitoring.GetNamespace, app.Routes, isProcessStatsEnabled(cfg.HTTP)) + s, err := monitoringServer.New(logger, endpointConfig, monitoring.GetNamespace, app.Routes, isProcessStatsEnabled(cfg.HTTP), tracer) if err != nil { return nil, errors.New(err, "could not start the HTTP server for the API") } @@ -374,3 +399,61 @@ func tryDelayEnroll(ctx context.Context, logger *logger.Logger, cfg *configurati logger.Info("Successfully performed delayed enrollment of this Elastic Agent.") return loadConfig(override) } + +func initTracer(agentName, version string, mcfg *monitoringCfg.MonitoringConfig) (*apm.Tracer, error) { + if !mcfg.Enabled || !mcfg.MonitorTraces { + return nil, nil + } + + cfg := mcfg.APM + + // TODO(stn): Ideally, we'd use apmtransport.NewHTTPTransportOptions() + // but it doesn't exist today. Update this code once we have something + // available via the APM Go agent. + const ( + envVerifyServerCert = "ELASTIC_APM_VERIFY_SERVER_CERT" + envServerCert = "ELASTIC_APM_SERVER_CERT" + envCACert = "ELASTIC_APM_SERVER_CA_CERT_FILE" + ) + if cfg.TLS.SkipVerify { + os.Setenv(envVerifyServerCert, "false") + defer os.Unsetenv(envVerifyServerCert) + } + if cfg.TLS.ServerCertificate != "" { + os.Setenv(envServerCert, cfg.TLS.ServerCertificate) + defer os.Unsetenv(envServerCert) + } + if cfg.TLS.ServerCA != "" { + os.Setenv(envCACert, cfg.TLS.ServerCA) + defer os.Unsetenv(envCACert) + } + + ts, err := apmtransport.NewHTTPTransport() + if err != nil { + return nil, err + } + + if len(cfg.Hosts) > 0 { + hosts := make([]*url.URL, 0, len(cfg.Hosts)) + for _, host := range cfg.Hosts { + u, err := url.Parse(host) + if err != nil { + return nil, fmt.Errorf("failed parsing %s: %w", host, err) + } + hosts = append(hosts, u) + } + ts.SetServerURL(hosts...) + } + if cfg.APIKey != "" { + ts.SetAPIKey(cfg.APIKey) + } else { + ts.SetSecretToken(cfg.SecretToken) + } + + return apm.NewTracerOptions(apm.TracerOptions{ + ServiceName: agentName, + ServiceVersion: version, + ServiceEnvironment: cfg.Environment, + Transport: ts, + }) +} diff --git a/x-pack/elastic-agent/pkg/agent/control/control_test.go b/x-pack/elastic-agent/pkg/agent/control/control_test.go index b37a161047f5..cdec30e4d4cc 100644 --- a/x-pack/elastic-agent/pkg/agent/control/control_test.go +++ b/x-pack/elastic-agent/pkg/agent/control/control_test.go @@ -8,6 +8,8 @@ import ( "context" "testing" + "go.elastic.co/apm" + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/core/status" "github.com/stretchr/testify/assert" @@ -22,7 +24,8 @@ import ( ) func TestServerClient_Version(t *testing.T) { - srv := server.New(newErrorLogger(t), nil, nil, nil) + tracer := apm.DefaultTracer + srv := server.New(newErrorLogger(t), nil, nil, nil, tracer) err := srv.Start() require.NoError(t, err) defer srv.Stop() @@ -46,7 +49,8 @@ func TestServerClient_Version(t *testing.T) { func TestServerClient_Status(t *testing.T) { l := newErrorLogger(t) statusCtrl := status.NewController(l) - srv := server.New(l, nil, statusCtrl, nil) + tracer := apm.DefaultTracer + srv := server.New(l, nil, statusCtrl, nil, tracer) err := srv.Start() require.NoError(t, err) defer srv.Stop() diff --git a/x-pack/elastic-agent/pkg/agent/control/server/server.go b/x-pack/elastic-agent/pkg/agent/control/server/server.go index 12ed4650eedf..34c9802e14e4 100644 --- a/x-pack/elastic-agent/pkg/agent/control/server/server.go +++ b/x-pack/elastic-agent/pkg/agent/control/server/server.go @@ -16,6 +16,8 @@ import ( "sync" "time" + "go.elastic.co/apm" + "go.elastic.co/apm/module/apmgrpc" "google.golang.org/grpc" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/application/reexec" @@ -45,6 +47,7 @@ type Server struct { monitoringCfg *monitoringCfg.MonitoringConfig listener net.Listener server *grpc.Server + tracer *apm.Tracer lock sync.RWMutex } @@ -59,11 +62,12 @@ type specInfo struct { } // New creates a new control protocol server. -func New(log *logger.Logger, rex reexec.ExecManager, statusCtrl status.Controller, up *upgrade.Upgrader) *Server { +func New(log *logger.Logger, rex reexec.ExecManager, statusCtrl status.Controller, up *upgrade.Upgrader, tracer *apm.Tracer) *Server { return &Server{ logger: log, rex: rex, statusCtrl: statusCtrl, + tracer: tracer, up: up, } } @@ -103,7 +107,12 @@ func (s *Server) Start() error { return err } s.listener = lis - s.server = grpc.NewServer() + if s.tracer != nil { + apmInterceptor := apmgrpc.NewUnaryServerInterceptor(apmgrpc.WithRecovery(), apmgrpc.WithTracer(s.tracer)) + s.server = grpc.NewServer(grpc.UnaryInterceptor(apmInterceptor)) + } else { + s.server = grpc.NewServer() + } proto.RegisterElasticAgentControlServer(s.server, s) // start serving GRPC connections diff --git a/x-pack/elastic-agent/pkg/agent/operation/common_test.go b/x-pack/elastic-agent/pkg/agent/operation/common_test.go index 7ebcb085555d..860239b2f7cb 100644 --- a/x-pack/elastic-agent/pkg/agent/operation/common_test.go +++ b/x-pack/elastic-agent/pkg/agent/operation/common_test.go @@ -12,6 +12,8 @@ import ( "testing" "time" + "go.elastic.co/apm" + "github.com/elastic/beats/v7/libbeat/logp" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/application/info" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/configuration" @@ -63,7 +65,8 @@ func getTestOperator(t *testing.T, downloadPath string, installPath string, p *a if err != nil { t.Fatal(err) } - srv, err := server.New(l, "localhost:0", &ApplicationStatusHandler{}) + tracer := apm.DefaultTracer + srv, err := server.New(l, "localhost:0", &ApplicationStatusHandler{}, tracer) if err != nil { t.Fatal(err) } diff --git a/x-pack/elastic-agent/pkg/agent/operation/monitoring_test.go b/x-pack/elastic-agent/pkg/agent/operation/monitoring_test.go index b01f296e01d7..07c3e169523f 100644 --- a/x-pack/elastic-agent/pkg/agent/operation/monitoring_test.go +++ b/x-pack/elastic-agent/pkg/agent/operation/monitoring_test.go @@ -11,6 +11,7 @@ import ( "time" "github.com/stretchr/testify/require" + "go.elastic.co/apm" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/program" @@ -164,7 +165,8 @@ func getMonitorableTestOperator(t *testing.T, installPath string, m monitoring.M if err != nil { t.Fatal(err) } - srv, err := server.New(l, "localhost:0", &ApplicationStatusHandler{}) + tracer := apm.DefaultTracer + srv, err := server.New(l, "localhost:0", &ApplicationStatusHandler{}, tracer) if err != nil { t.Fatal(err) } diff --git a/x-pack/elastic-agent/pkg/agent/operation/operator.go b/x-pack/elastic-agent/pkg/agent/operation/operator.go index 8e83efbd94ba..9b0cab9fc714 100644 --- a/x-pack/elastic-agent/pkg/agent/operation/operator.go +++ b/x-pack/elastic-agent/pkg/agent/operation/operator.go @@ -12,6 +12,8 @@ import ( "sync" "time" + "go.elastic.co/apm" + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/application/info" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/configrequest" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/configuration" @@ -155,13 +157,18 @@ func (o *Operator) Close() error { o.monitor.Close() o.statusReporter.Unregister() - return o.HandleConfig(configrequest.New("", time.Now(), nil)) + return o.HandleConfig(context.Background(), configrequest.New("", time.Now(), nil)) } // HandleConfig handles configuration for a pipeline and performs actions to achieve this configuration. -func (o *Operator) HandleConfig(cfg configrequest.Request) (err error) { +func (o *Operator) HandleConfig(ctx context.Context, cfg configrequest.Request) (err error) { + // TODO: double check `route` as name + span, ctx := apm.StartSpan(ctx, "route", "app.internal") defer func() { - err = filterContextCancelled(err) + if err = filterContextCancelled(err); err != nil { + apm.CaptureError(ctx, err).Send() + } + span.End() }() _, stateID, steps, ack, err := o.stateResolver.Resolve(cfg) diff --git a/x-pack/elastic-agent/pkg/agent/storage/store/state_store.go b/x-pack/elastic-agent/pkg/agent/storage/store/state_store.go index 902e5f9f746c..b1002871acbd 100644 --- a/x-pack/elastic-agent/pkg/agent/storage/store/state_store.go +++ b/x-pack/elastic-agent/pkg/agent/storage/store/state_store.go @@ -20,7 +20,7 @@ import ( ) type dispatcher interface { - Dispatch(acker FleetAcker, actions ...action) error + Dispatch(context.Context, FleetAcker, ...action) error } type store interface { @@ -319,6 +319,7 @@ func (a *StateStoreActionAcker) Commit(ctx context.Context) error { // ReplayActions replays list of actions. func ReplayActions( + ctx context.Context, log *logger.Logger, dispatcher dispatcher, acker FleetAcker, @@ -326,7 +327,7 @@ func ReplayActions( ) error { log.Info("restoring current policy from disk") - if err := dispatcher.Dispatch(acker, actions...); err != nil { + if err := dispatcher.Dispatch(ctx, acker, actions...); err != nil { return err } diff --git a/x-pack/elastic-agent/pkg/artifact/download/composed/downloader.go b/x-pack/elastic-agent/pkg/artifact/download/composed/downloader.go index d500a1f8cc1f..de166e6f7195 100644 --- a/x-pack/elastic-agent/pkg/artifact/download/composed/downloader.go +++ b/x-pack/elastic-agent/pkg/artifact/download/composed/downloader.go @@ -8,6 +8,7 @@ import ( "context" "github.com/hashicorp/go-multierror" + "go.elastic.co/apm" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/program" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/artifact/download" @@ -35,6 +36,8 @@ func NewDownloader(downloaders ...download.Downloader) *Downloader { // Returns absolute path to downloaded package and an error. func (e *Downloader) Download(ctx context.Context, spec program.Spec, version string) (string, error) { var err error + span, ctx := apm.StartSpan(ctx, "download", "app.internal") + defer span.End() for _, d := range e.dd { s, e := d.Download(ctx, spec, version) diff --git a/x-pack/elastic-agent/pkg/artifact/download/fs/downloader.go b/x-pack/elastic-agent/pkg/artifact/download/fs/downloader.go index 3d055e69e65b..74092176d0f3 100644 --- a/x-pack/elastic-agent/pkg/artifact/download/fs/downloader.go +++ b/x-pack/elastic-agent/pkg/artifact/download/fs/downloader.go @@ -11,6 +11,8 @@ import ( "os" "path/filepath" + "go.elastic.co/apm" + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/program" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/application/paths" @@ -38,13 +40,16 @@ func NewDownloader(config *artifact.Config) *Downloader { // Download fetches the package from configured source. // Returns absolute path to downloaded package and an error. -func (e *Downloader) Download(_ context.Context, spec program.Spec, version string) (_ string, err error) { +func (e *Downloader) Download(ctx context.Context, spec program.Spec, version string) (_ string, err error) { + span, ctx := apm.StartSpan(ctx, "download", "app.internal") + defer span.End() downloadedFiles := make([]string, 0, 2) defer func() { if err != nil { for _, path := range downloadedFiles { os.Remove(path) } + apm.CaptureError(ctx, err).Send() } }() diff --git a/x-pack/elastic-agent/pkg/basecmd/version/cmd_test.go b/x-pack/elastic-agent/pkg/basecmd/version/cmd_test.go index 81fb5a56d8f9..0d33823cc888 100644 --- a/x-pack/elastic-agent/pkg/basecmd/version/cmd_test.go +++ b/x-pack/elastic-agent/pkg/basecmd/version/cmd_test.go @@ -11,6 +11,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "go.elastic.co/apm" "gopkg.in/yaml.v2" "github.com/elastic/beats/v7/libbeat/logp" @@ -54,7 +55,8 @@ func TestCmdBinaryOnlyYAML(t *testing.T) { } func TestCmdDaemon(t *testing.T) { - srv := server.New(newErrorLogger(t), nil, nil, nil) + tracer := apm.DefaultTracer + srv := server.New(newErrorLogger(t), nil, nil, nil, tracer) require.NoError(t, srv.Start()) defer srv.Stop() @@ -70,7 +72,8 @@ func TestCmdDaemon(t *testing.T) { } func TestCmdDaemonYAML(t *testing.T) { - srv := server.New(newErrorLogger(t), nil, nil, nil) + tracer := apm.DefaultTracer + srv := server.New(newErrorLogger(t), nil, nil, nil, tracer) require.NoError(t, srv.Start()) defer srv.Stop() diff --git a/x-pack/elastic-agent/pkg/core/monitoring/config/config.go b/x-pack/elastic-agent/pkg/core/monitoring/config/config.go index 3004561bd862..ea98053d0d99 100644 --- a/x-pack/elastic-agent/pkg/core/monitoring/config/config.go +++ b/x-pack/elastic-agent/pkg/core/monitoring/config/config.go @@ -16,6 +16,8 @@ type MonitoringConfig struct { HTTP *MonitoringHTTPConfig `yaml:"http" config:"http"` Namespace string `yaml:"namespace" config:"namespace"` Pprof *PprofConfig `yaml:"pprof" config:"pprof"` + MonitorTraces bool `yaml:"traces" config:"traces"` + APM APMConfig `yaml:"apm,omitempty" config:"apm,omitempty" json:"apm,omitempty"` } // MonitoringHTTPConfig is a config defining HTTP endpoint published by agent @@ -41,10 +43,33 @@ func DefaultConfig() *MonitoringConfig { MonitorLogs: true, MonitorMetrics: true, LogMetrics: true, + MonitorTraces: false, HTTP: &MonitoringHTTPConfig{ Enabled: false, Port: defaultPort, }, Namespace: defaultNamespace, + APM: defaultAPMConfig(), } } + +// APMConfig configures APM Tracing. +type APMConfig struct { + Environment string `config:"environment"` + APIKey string `config:"api_key"` + SecretToken string `config:"secret_token"` + Hosts []string `config:"hosts"` + TLS APMTLS `config:"tls"` +} + +// APMTLS contains the configuration options necessary for configuring TLS in +// apm-agent-go. +type APMTLS struct { + SkipVerify bool `config:"skip_verify"` + ServerCertificate string `config:"server_certificate"` + ServerCA string `config:"server_ca"` +} + +func defaultAPMConfig() APMConfig { + return APMConfig{} +} diff --git a/x-pack/elastic-agent/pkg/core/monitoring/config/config_test.go b/x-pack/elastic-agent/pkg/core/monitoring/config/config_test.go new file mode 100644 index 000000000000..0f37fea591c2 --- /dev/null +++ b/x-pack/elastic-agent/pkg/core/monitoring/config/config_test.go @@ -0,0 +1,66 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License; +// you may not use this file except in compliance with the Elastic License. + +package config + +import ( + "testing" + + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/config" + + "github.com/stretchr/testify/require" + "gotest.tools/assert" +) + +func TestAPMConfig(t *testing.T) { + tcs := map[string]struct { + in map[string]interface{} + out APMConfig + }{ + "default": { + in: map[string]interface{}{}, + out: defaultAPMConfig(), + }, + "custom": { + in: map[string]interface{}{ + "traces": true, + "apm": map[string]interface{}{ + "api_key": "abc123", + "environment": "production", + "hosts": []string{"https://abc.123.com"}, + "tls": map[string]interface{}{ + "skip_verify": true, + "server_certificate": "server_cert", + "server_ca": "server_ca", + }, + }, + }, + out: APMConfig{ + APIKey: "abc123", + Environment: "production", + Hosts: []string{"https://abc.123.com"}, + TLS: APMTLS{ + SkipVerify: true, + ServerCertificate: "server_cert", + ServerCA: "server_ca", + }, + }, + }, + } + + for name, tc := range tcs { + t.Run(name, func(t *testing.T) { + in, err := config.NewConfigFrom(tc.in) + require.NoError(t, err) + + cfg := DefaultConfig() + require.NoError(t, in.Unpack(cfg)) + + require.NoError(t, err) + require.NotNil(t, cfg) + instCfg := cfg.APM + assert.DeepEqual(t, tc.out, instCfg) + }) + } +} diff --git a/x-pack/elastic-agent/pkg/core/monitoring/server/server.go b/x-pack/elastic-agent/pkg/core/monitoring/server/server.go index 5d74221236f5..6cbd7692ede1 100644 --- a/x-pack/elastic-agent/pkg/core/monitoring/server/server.go +++ b/x-pack/elastic-agent/pkg/core/monitoring/server/server.go @@ -13,6 +13,8 @@ import ( "strings" "github.com/gorilla/mux" + "go.elastic.co/apm" + "go.elastic.co/apm/module/apmgorilla" "github.com/elastic/beats/v7/libbeat/api" "github.com/elastic/beats/v7/libbeat/common" @@ -28,6 +30,7 @@ func New( ns func(string) *monitoring.Namespace, routesFetchFn func() *sorted.Set, enableProcessStats bool, + tracer *apm.Tracer, ) (*api.Server, error) { if err := createAgentMonitoringDrop(endpointConfig.Host); err != nil { // log but ignore @@ -39,11 +42,21 @@ func New( return nil, err } - return exposeMetricsEndpoint(log, cfg, ns, routesFetchFn, enableProcessStats) + return exposeMetricsEndpoint(log, cfg, ns, routesFetchFn, enableProcessStats, tracer) } -func exposeMetricsEndpoint(log *logger.Logger, config *common.Config, ns func(string) *monitoring.Namespace, routesFetchFn func() *sorted.Set, enableProcessStats bool) (*api.Server, error) { +func exposeMetricsEndpoint( + log *logger.Logger, + config *common.Config, + ns func(string) *monitoring.Namespace, + routesFetchFn func() *sorted.Set, + enableProcessStats bool, + tracer *apm.Tracer, +) (*api.Server, error) { r := mux.NewRouter() + if tracer != nil { + r.Use(apmgorilla.Middleware(apmgorilla.WithTracer(tracer))) + } statsHandler := statsHandler(ns("stats")) r.Handle("/stats", createHandler(statsHandler)) diff --git a/x-pack/elastic-agent/pkg/core/server/config.go b/x-pack/elastic-agent/pkg/core/server/config.go index 283bd58a4634..74d68b4ef5a2 100644 --- a/x-pack/elastic-agent/pkg/core/server/config.go +++ b/x-pack/elastic-agent/pkg/core/server/config.go @@ -7,6 +7,8 @@ package server import ( "fmt" + "go.elastic.co/apm" + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/core/logger" ) @@ -25,6 +27,6 @@ func DefaultGRPCConfig() *Config { } // NewFromConfig creates a new GRPC server for clients to connect to. -func NewFromConfig(logger *logger.Logger, cfg *Config, handler Handler) (*Server, error) { - return New(logger, fmt.Sprintf("%s:%d", cfg.Address, cfg.Port), handler) +func NewFromConfig(logger *logger.Logger, cfg *Config, handler Handler, tracer *apm.Tracer) (*Server, error) { + return New(logger, fmt.Sprintf("%s:%d", cfg.Address, cfg.Port), handler, tracer) } diff --git a/x-pack/elastic-agent/pkg/core/server/config_test.go b/x-pack/elastic-agent/pkg/core/server/config_test.go index 444b73dffd23..2c846d77892c 100644 --- a/x-pack/elastic-agent/pkg/core/server/config_test.go +++ b/x-pack/elastic-agent/pkg/core/server/config_test.go @@ -17,7 +17,7 @@ func TestNewFromConfig(t *testing.T) { Address: "0.0.0.0", Port: 9876, } - srv, err := NewFromConfig(l, cfg, &StubHandler{}) + srv, err := NewFromConfig(l, cfg, &StubHandler{}, nil) require.NoError(t, err) assert.Equal(t, "0.0.0.0:9876", srv.getListenAddr()) } diff --git a/x-pack/elastic-agent/pkg/core/server/server.go b/x-pack/elastic-agent/pkg/core/server/server.go index f584e70bad25..dec1241a1a3c 100644 --- a/x-pack/elastic-agent/pkg/core/server/server.go +++ b/x-pack/elastic-agent/pkg/core/server/server.go @@ -15,6 +15,8 @@ import ( "sync" "time" + "go.elastic.co/apm" + "go.elastic.co/apm/module/apmgrpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -101,6 +103,7 @@ type Server struct { ca *authority.CertificateAuthority listenAddr string handler Handler + tracer *apm.Tracer listener net.Listener server *grpc.Server @@ -115,7 +118,7 @@ type Server struct { } // New creates a new GRPC server for clients to connect to. -func New(logger *logger.Logger, listenAddr string, handler Handler) (*Server, error) { +func New(logger *logger.Logger, listenAddr string, handler Handler, tracer *apm.Tracer) (*Server, error) { ca, err := authority.NewCA() if err != nil { return nil, err @@ -127,6 +130,7 @@ func New(logger *logger.Logger, listenAddr string, handler Handler) (*Server, er handler: handler, watchdogCheckInterval: WatchdogCheckLoop, checkInMinTimeout: client.CheckinMinimumTimeout + CheckinMinimumTimeoutGracePeriod, + tracer: tracer, }, nil } @@ -151,7 +155,15 @@ func (s *Server) Start() error { ClientCAs: certPool, GetCertificate: s.getCertificate, }) - s.server = grpc.NewServer(grpc.Creds(creds)) + if s.tracer != nil { + apmInterceptor := apmgrpc.NewUnaryServerInterceptor(apmgrpc.WithRecovery(), apmgrpc.WithTracer(s.tracer)) + s.server = grpc.NewServer( + grpc.UnaryInterceptor(apmInterceptor), + grpc.Creds(creds), + ) + } else { + s.server = grpc.NewServer() + } proto.RegisterElasticAgentServer(s.server, s) // start serving GRPC connections diff --git a/x-pack/elastic-agent/pkg/core/server/server_test.go b/x-pack/elastic-agent/pkg/core/server/server_test.go index b879d53728da..a883fb76a8d0 100644 --- a/x-pack/elastic-agent/pkg/core/server/server_test.go +++ b/x-pack/elastic-agent/pkg/core/server/server_test.go @@ -13,6 +13,7 @@ import ( "testing" "time" + "go.elastic.co/apm" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -634,7 +635,8 @@ func newErrorLogger(t *testing.T) *logger.Logger { func createAndStartServer(t *testing.T, handler Handler, extraConfigs ...func(*Server)) *Server { t.Helper() - srv, err := New(newErrorLogger(t), "localhost:0", handler) + tracer := apm.DefaultTracer + srv, err := New(newErrorLogger(t), "localhost:0", handler, tracer) require.NoError(t, err) for _, extra := range extraConfigs { extra(srv) diff --git a/x-pack/elastic-agent/pkg/fleetapi/ack_cmd.go b/x-pack/elastic-agent/pkg/fleetapi/ack_cmd.go index 5002fc36ffe7..189446130360 100644 --- a/x-pack/elastic-agent/pkg/fleetapi/ack_cmd.go +++ b/x-pack/elastic-agent/pkg/fleetapi/ack_cmd.go @@ -11,6 +11,8 @@ import ( "fmt" "net/http" + "go.elastic.co/apm" + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/errors" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/fleetapi/client" ) @@ -79,24 +81,29 @@ func NewAckCmd(info agentInfo, client client.Sender) *AckCmd { // Execute ACK of actions to the Fleet. func (e *AckCmd) Execute(ctx context.Context, r *AckRequest) (*AckResponse, error) { - if err := r.Validate(); err != nil { + var err error + span, ctx := apm.StartSpan(ctx, "execute", "app.internal") + defer func() { + if err != nil { + apm.CaptureError(ctx, err).Send() + } + span.End() + }() + if err = r.Validate(); err != nil { return nil, err } - b, err := json.Marshal(r) - if err != nil { - return nil, errors.New(err, - "fail to encode the ack request", - errors.TypeUnexpected) + b, mErr := json.Marshal(r) + if mErr != nil { + err = errors.New(mErr, "fail to encode the ack request", errors.TypeUnexpected) + return nil, err } ap := fmt.Sprintf(ackPath, e.info.AgentID()) - resp, err := e.client.Send(ctx, "POST", ap, nil, nil, bytes.NewBuffer(b)) - if err != nil { - return nil, errors.New(err, - "fail to ack to fleet", - errors.TypeNetwork, - errors.M(errors.MetaKeyURI, ap)) + resp, mErr := e.client.Send(ctx, "POST", ap, nil, nil, bytes.NewBuffer(b)) + if mErr != nil { + err = errors.New(mErr, "fail to ack to fleet", errors.TypeNetwork, errors.M(errors.MetaKeyURI, ap)) + return nil, err } defer resp.Body.Close() @@ -106,14 +113,15 @@ func (e *AckCmd) Execute(ctx context.Context, r *AckRequest) (*AckResponse, erro ackResponse := &AckResponse{} decoder := json.NewDecoder(resp.Body) - if err := decoder.Decode(ackResponse); err != nil { - return nil, errors.New(err, + if err = decoder.Decode(ackResponse); err != nil { + err = errors.New(err, "fail to decode ack response", errors.TypeNetwork, errors.M(errors.MetaKeyURI, ap)) + return nil, err } - if err := ackResponse.Validate(); err != nil { + if err = ackResponse.Validate(); err != nil { return nil, err } diff --git a/x-pack/elastic-agent/pkg/fleetapi/acker/fleet/fleet_acker.go b/x-pack/elastic-agent/pkg/fleetapi/acker/fleet/fleet_acker.go index fcc74f17205e..34c7402c592f 100644 --- a/x-pack/elastic-agent/pkg/fleetapi/acker/fleet/fleet_acker.go +++ b/x-pack/elastic-agent/pkg/fleetapi/acker/fleet/fleet_acker.go @@ -10,6 +10,8 @@ import ( "strings" "time" + "go.elastic.co/apm" + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/errors" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/core/logger" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/fleetapi" @@ -48,7 +50,14 @@ func (f *Acker) SetClient(c client.Sender) { } // Ack acknowledges action. -func (f *Acker) Ack(ctx context.Context, action fleetapi.Action) error { +func (f *Acker) Ack(ctx context.Context, action fleetapi.Action) (err error) { + span, ctx := apm.StartSpan(ctx, "ack", "app.internal") + defer func() { + if err != nil { + apm.CaptureError(ctx, err).Send() + } + span.End() + }() // checkin agentID := f.agentInfo.AgentID() cmd := fleetapi.NewAckCmd(f.agentInfo, f.client) @@ -58,7 +67,7 @@ func (f *Acker) Ack(ctx context.Context, action fleetapi.Action) error { }, } - _, err := cmd.Execute(ctx, req) + _, err = cmd.Execute(ctx, req) if err != nil { return errors.New(err, fmt.Sprintf("acknowledge action '%s' for elastic-agent '%s' failed", action.ID(), agentID), errors.TypeNetwork) } @@ -69,7 +78,14 @@ func (f *Acker) Ack(ctx context.Context, action fleetapi.Action) error { } // AckBatch acknowledges multiple actions at once. -func (f *Acker) AckBatch(ctx context.Context, actions []fleetapi.Action) error { +func (f *Acker) AckBatch(ctx context.Context, actions []fleetapi.Action) (err error) { + span, ctx := apm.StartSpan(ctx, "ackBatch", "app.internal") + defer func() { + if err != nil { + apm.CaptureError(ctx, err).Send() + } + span.End() + }() // checkin agentID := f.agentInfo.AgentID() events := make([]fleetapi.AckEvent, 0, len(actions)) @@ -91,7 +107,7 @@ func (f *Acker) AckBatch(ctx context.Context, actions []fleetapi.Action) error { f.log.Debugf("%d actions with ids '%s' acknowledging", len(ids), strings.Join(ids, ",")) - _, err := cmd.Execute(ctx, req) + _, err = cmd.Execute(ctx, req) if err != nil { return errors.New(err, fmt.Sprintf("acknowledge %d actions '%v' for elastic-agent '%s' failed", len(actions), actions, agentID), errors.TypeNetwork) } diff --git a/x-pack/elastic-agent/pkg/fleetapi/acker/lazy/lazy_acker.go b/x-pack/elastic-agent/pkg/fleetapi/acker/lazy/lazy_acker.go index c48ac0042334..e1fb9c2e8f84 100644 --- a/x-pack/elastic-agent/pkg/fleetapi/acker/lazy/lazy_acker.go +++ b/x-pack/elastic-agent/pkg/fleetapi/acker/lazy/lazy_acker.go @@ -7,6 +7,8 @@ package lazy import ( "context" + "go.elastic.co/apm" + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/core/logger" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/fleetapi" ) @@ -36,19 +38,34 @@ func NewAcker(baseAcker batchAcker, log *logger.Logger) *Acker { } // Ack acknowledges action. -func (f *Acker) Ack(ctx context.Context, action fleetapi.Action) error { +func (f *Acker) Ack(ctx context.Context, action fleetapi.Action) (err error) { + span, ctx := apm.StartSpan(ctx, "ack", "app.internal") + defer func() { + if err != nil { + apm.CaptureError(ctx, err).Send() + } + span.End() + }() f.enqueue(action) if _, isAckForced := action.(ackForcer); isAckForced { - return f.Commit(ctx) + err = f.Commit(ctx) + return } return nil } // Commit commits ack actions. -func (f *Acker) Commit(ctx context.Context) error { - err := f.acker.AckBatch(ctx, f.queue) +func (f *Acker) Commit(ctx context.Context) (err error) { + span, ctx := apm.StartSpan(ctx, "commit", "app.internal") + defer func() { + if err != nil { + apm.CaptureError(ctx, err).Send() + } + span.End() + }() + err = f.acker.AckBatch(ctx, f.queue) if err != nil { // do not cleanup on error return err diff --git a/x-pack/elastic-agent/pkg/fleetapi/client/client.go b/x-pack/elastic-agent/pkg/fleetapi/client/client.go index 172600cfede5..96a575858528 100644 --- a/x-pack/elastic-agent/pkg/fleetapi/client/client.go +++ b/x-pack/elastic-agent/pkg/fleetapi/client/client.go @@ -14,6 +14,8 @@ import ( "net/url" "os" + "go.elastic.co/apm/module/apmhttp" + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/errors" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/core/logger" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/release" @@ -36,7 +38,7 @@ type Sender interface { var baseRoundTrippers = func(rt http.RoundTripper) (http.RoundTripper, error) { rt = NewFleetUserAgentRoundTripper(rt, release.Version()) - return rt, nil + return apmhttp.WrapRoundTripper(rt), nil } func init() { diff --git a/x-pack/elastic-agent/pkg/remote/client.go b/x-pack/elastic-agent/pkg/remote/client.go index 23f6162c08e3..fe4608372313 100644 --- a/x-pack/elastic-agent/pkg/remote/client.go +++ b/x-pack/elastic-agent/pkg/remote/client.go @@ -15,6 +15,7 @@ import ( "time" "github.com/pkg/errors" + "go.elastic.co/apm/module/apmhttp" "github.com/elastic/beats/v7/libbeat/common" "github.com/elastic/beats/v7/libbeat/common/transport/httpcommon" @@ -124,6 +125,8 @@ func NewWithConfig(log *logger.Logger, cfg Config, wrapper wrapperFunc) (*Client } } + transport = apmhttp.WrapRoundTripper(transport) + httpClient := http.Client{ Transport: transport, Timeout: cfg.Transport.Timeout,