├── .editorconfig ├── .eslintrc ├── .github └── dependabot.yml ├── .gitignore ├── .travis.yml ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── build.config.js ├── changelog ├── 5.1.0-rc.1 │ └── .gitkeep └── unreleased │ └── .gitkeep ├── jenkins.groovy ├── package.json ├── pom.xml ├── src ├── deb │ └── control │ │ └── control ├── main │ ├── java │ │ └── org │ │ │ └── graylog │ │ │ └── plugins │ │ │ └── collector │ │ │ ├── CollectorMetaData.java │ │ │ ├── CollectorModule.java │ │ │ ├── CollectorPlugin.java │ │ │ ├── audit │ │ │ └── CollectorAuditEventTypes.java │ │ │ ├── collectors │ │ │ ├── Collector.java │ │ │ ├── CollectorActions.java │ │ │ ├── CollectorImpl.java │ │ │ ├── CollectorNodeDetails.java │ │ │ ├── CollectorService.java │ │ │ ├── CollectorServiceImpl.java │ │ │ ├── CollectorUpload.java │ │ │ ├── Collectors.java │ │ │ └── rest │ │ │ │ ├── CollectorResource.java │ │ │ │ └── models │ │ │ │ ├── CollectorAction.java │ │ │ │ ├── CollectorLogFile.java │ │ │ │ ├── CollectorMetrics.java │ │ │ │ ├── CollectorNodeDetailsSummary.java │ │ │ │ ├── CollectorStatus.java │ │ │ │ ├── CollectorStatusList.java │ │ │ │ ├── requests │ │ │ │ └── CollectorRegistrationRequest.java │ │ │ │ └── responses │ │ │ │ ├── CollectorList.java │ │ │ │ ├── CollectorRegistrationAction.java │ │ │ │ ├── CollectorRegistrationConfiguration.java │ │ │ │ ├── CollectorRegistrationResponse.java │ │ │ │ └── CollectorSummary.java │ │ │ ├── common │ │ │ └── CollectorPluginConfiguration.java │ │ │ ├── configurations │ │ │ ├── CollectorConfigurationService.java │ │ │ └── rest │ │ │ │ ├── CollectorConfigurationEtagInvalidation.java │ │ │ │ ├── ConfigurationEtagService.java │ │ │ │ ├── models │ │ │ │ ├── CollectorConfiguration.java │ │ │ │ ├── CollectorConfigurationSnippet.java │ │ │ │ ├── CollectorConfigurationSummary.java │ │ │ │ ├── CollectorInput.java │ │ │ │ └── CollectorOutput.java │ │ │ │ ├── resources │ │ │ │ └── CollectorConfigurationResource.java │ │ │ │ └── responses │ │ │ │ ├── CollectorConfigurationListResponse.java │ │ │ │ ├── CollectorInputListResponse.java │ │ │ │ ├── CollectorOutputListResponse.java │ │ │ │ └── CollectorSnippetListResponse.java │ │ │ ├── periodical │ │ │ └── PurgeExpiredCollectorsThread.java │ │ │ ├── permissions │ │ │ └── CollectorRestPermissions.java │ │ │ └── system │ │ │ ├── CollectorSystemConfiguration.java │ │ │ └── CollectorSystemConfigurationSupplier.java │ └── resources │ │ ├── META-INF │ │ └── services │ │ │ └── org.graylog2.plugin.Plugin │ │ ├── org.graylog.plugins.graylog-plugin-collector │ │ └── graylog-plugin.properties │ │ └── snippets │ │ └── defaults │ │ └── nxlog.tmpl ├── test │ ├── java │ │ └── org │ │ │ └── graylog │ │ │ └── plugins │ │ │ └── collector │ │ │ └── collectors │ │ │ ├── CollectorServiceImplTest.java │ │ │ ├── CollectorTestPasswordSecretModule.java │ │ │ └── rest │ │ │ ├── CollectorResourceTest.java │ │ │ ├── assertj │ │ │ └── ResponseAssert.java │ │ │ └── resources │ │ │ └── RestResourceBaseTest.java │ └── resources │ │ └── org │ │ └── graylog │ │ └── plugins │ │ └── collector │ │ └── collectors │ │ ├── CollectorServiceImplTest#testDestroy-expected.json │ │ ├── collectorsMultipleDocuments.json │ │ └── collectorsSingleDataset.json └── web │ ├── collector-configuration │ ├── CollapsibleVerbatim.jsx │ ├── CollectorConfiguration.jsx │ ├── CollectorConfigurationPage.jsx │ ├── CopyInputModal.jsx │ ├── CopyOutputModal.jsx │ ├── CopySnippetModal.jsx │ ├── DeleteConfirmButton.jsx │ ├── EditInputFields.jsx │ ├── EditInputModal.jsx │ ├── EditOutputFields.jsx │ ├── EditOutputModal.jsx │ ├── EditSnippetModal.jsx │ └── TagsSelect.jsx │ ├── collectors │ ├── CollectorFilter.jsx │ ├── CollectorRow.jsx │ ├── CollectorsActions.js │ ├── CollectorsImportButton.jsx │ ├── CollectorsList.jsx │ ├── CollectorsPage.css │ ├── CollectorsPage.jsx │ ├── CollectorsPageNavigation.tsx │ ├── CollectorsRestartButton.jsx │ ├── CollectorsStatusFileList.jsx │ ├── CollectorsStatusPage.jsx │ ├── CollectorsStore.js │ └── ImportsHelperModal.jsx │ ├── configurations │ ├── CollectorConfigurationsActions.jsx │ ├── CollectorConfigurationsStore.js │ ├── ConfigurationRow.jsx │ ├── ConfigurationsList.jsx │ ├── ConfigurationsPage.jsx │ ├── CopyConfigurationModal.jsx │ └── EditConfigurationModal.jsx │ ├── index.jsx │ ├── styles │ └── CollectorStyles.lazy.css │ ├── system-configuration │ └── CollectorSystemConfiguration.jsx │ └── webpack-entry.js ├── webpack.config.js └── yarn.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*.{js,ts,jsx}] 4 | indent_style = space 5 | indent_size = 2 6 | insert_final_newline = true 7 | 8 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "babel-eslint", 3 | "ecmaFeatures": { 4 | "classes": true, 5 | "jsx": true, 6 | }, 7 | "extends": [ 8 | "graylog", 9 | ], 10 | } 11 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: npm 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | time: "11:00" 8 | open-pull-requests-limit: 10 9 | ignore: 10 | - dependency-name: y18n 11 | versions: 12 | - 4.0.1 13 | - 4.0.2 14 | - dependency-name: lodash 15 | versions: 16 | - 4.17.20 17 | - dependency-name: semver 18 | versions: 19 | - 7.3.4 20 | - dependency-name: elliptic 21 | versions: 22 | - 6.5.3 23 | - package-ecosystem: maven 24 | directory: "/" 25 | schedule: 26 | interval: daily 27 | time: "11:00" 28 | open-pull-requests-limit: 10 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | *.iml 3 | *.ipr 4 | *.iws 5 | .classpath 6 | .project 7 | .settings/ 8 | build/ 9 | node/ 10 | node_modules/ 11 | target/ 12 | cache/ 13 | dependency-reduced-pom.xml 14 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: java 3 | jdk: 4 | - oraclejdk8 5 | addons: 6 | apt: 7 | packages: 8 | - rpm 9 | install: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -Dskip.web.build=true -B -V 10 | script: mvn package verify -Dskip.web.build=true -B -V 11 | before_deploy: 12 | - mvn jdeb:jdeb && export RELEASE_DEB_FILE=$(ls target/*.deb) 13 | - mvn rpm:rpm && export RELEASE_RPM_FILE=$(find target/ -name '*.rpm' | tail -1) 14 | - rm -f target/original-*.jar 15 | - export RELEASE_PKG_FILE=$(ls target/*.jar) 16 | - echo "Deploying release to GitHub releases" 17 | deploy: 18 | provider: releases 19 | api_key: 20 | secure: lxv594nVRmUfzitvACxdiUaezogPWfaONBrj0h1E8nTtV+bxmozuDTAv9uxX31t0uIWfTkm9EIFdamRMv5lS+1XuwbUSD36oMxSNopnlMSTS6ll1jqjenIrXhd2qk47K/LDWK1wjuTjLPRj0IkfWcJK2wG1trSaR7oWlsmdpZ8hy+WEb0wjx9Yy6Xwq2Dco0klgs8KTxIIyiVRDFLsAY4w9PymXnpOjpr3zQ2efICEQOslsl1DcqwNV1hL0VjqZgeaIjneg9e1nUVc7w1xgIaOjNQE9/oHzdV4ESmsDhUuRQKRMsqfJjXelgBbGo2QAtnvoQkD93msVhbOWvWwo35HT7bLpn3AmL93ejFOxI+QFPF8u5nFsduzvhEQucvFgMaCiq31bN5GjJHrku+zRyjA/JXPd1D4GRJ99enIjsRLaRW7l7gxsOuuLyI69QnvjA1Dw9yy6d2UICKTMcNCnADB3yrSPB1Ne0SS4/Wf5afF4T+7uv4X2Dw70dBC44euE04cKnR06rjmIg81Z0WWzfbdlxLPXySkJiY0XyLl+ysRIJD0o1iYCQqOVQ01hFguH+4k88N4ftvh8IypU4Cb3MgrP+OuyOsFx1RHM/ajwPv3UCFRVAlfkEwXITPjnPcyOiQgFBvO9n9PGLgTwzF3V/2M7LcCiw3oEUgYrbJg1yfdQ= 21 | file: 22 | - "${RELEASE_PKG_FILE}" 23 | - "${RELEASE_DEB_FILE}" 24 | - "${RELEASE_RPM_FILE}" 25 | skip_cleanup: true 26 | on: 27 | tags: true 28 | jdk: oraclejdk8 29 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, gender identity and expression, level of experience, 9 | nationality, personal appearance, race, religion, or sexual identity and 10 | orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at . All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at [http://contributor-covenant.org/version/1/4][version] 72 | 73 | [homepage]: http://contributor-covenant.org 74 | [version]: http://contributor-covenant.org/version/1/4/ 75 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Please follow [the instructions on graylog.org](https://www.graylog.org/contributing-to-graylog/). 2 | 3 | #### Code of Conduct 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, gender identity and expression, level of experience, 9 | nationality, personal appearance, race, religion, or sexual identity and 10 | orientation. 11 | 12 | Please read and understand the [Code of Conduct](https://github.com/Graylog2/graylog-plugin-collector/blob/master/CODE_OF_CONDUCT.md). 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Collector Plugin for Graylog 2 | 3 | [![Build Status](https://travis-ci.org/Graylog2/graylog-plugin-collector.svg?branch=master)](https://travis-ci.org/Graylog2/graylog-plugin-collector) 4 | 5 | Graylog Collector is a lightweight Java application that allows you to forward data from log files to a Graylog cluster. The collector can read local log files and also Windows Events natively, it then can forward the log messages over the network using the [GELF format](https://docs.graylog.org/en/2.5/pages/gelf.html). 6 | 7 | 8 | > :warning: The Graylog Collector Sidecar is deprecated and can be replaced with [Graylog Sidecar](https://docs.graylog.org/en/latest/pages/sidecar.html) 9 | 10 | 11 | **Required Graylog version:** 2.0 and later 12 | 13 | Installation 14 | ------------ 15 | 16 | [Download the plugin](https://github.com/Graylog2/graylog-plugin-collector/releases) 17 | and place the `.jar` file in your Graylog plugin directory. The plugin directory 18 | is the `plugins/` folder relative from your `graylog-server` directory by default 19 | and can be configured in your `graylog.conf` file. 20 | 21 | Restart `graylog-server` and you are done. 22 | 23 | Development 24 | ----------- 25 | 26 | You can improve your development experience for the web interface part of your plugin 27 | dramatically by making use of hot reloading. To do this, do the following: 28 | 29 | * `git clone https://github.com/Graylog2/graylog2-server.git` 30 | * `cd graylog2-server/graylog2-web-interface` 31 | * `ln -s $YOURPLUGIN plugin/` 32 | * `npm install && npm start` 33 | 34 | Usage 35 | ----- 36 | 37 | Please refer to the [Documentation](https://docs.graylog.org/en/2.5/pages/collector.html). 38 | 39 | 40 | Getting started 41 | --------------- 42 | 43 | This project is using Maven 3 and requires Java 7 or higher. 44 | 45 | * Clone this repository. 46 | * Run `mvn package` to build a JAR file. 47 | * Optional: Run `mvn jdeb:jdeb` and `mvn rpm:rpm` to create a DEB and RPM package respectively. 48 | * Copy generated JAR file in target directory to your Graylog plugin directory. 49 | * Restart the Graylog. 50 | 51 | Plugin Release 52 | -------------- 53 | 54 | We are using the maven release plugin: 55 | 56 | ``` 57 | $ mvn release:prepare 58 | [...] 59 | $ mvn release:perform 60 | ``` 61 | 62 | This sets the version numbers, creates a tag and pushes to GitHub. Travis CI will build the release artifacts and upload to GitHub automatically. 63 | -------------------------------------------------------------------------------- /build.config.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | const path = require('path'); 18 | 19 | module.exports = { 20 | // Make sure that this is the correct path to the web interface part of the Graylog server repository. 21 | web_src_path: path.resolve(__dirname, '../graylog2-server/graylog2-web-interface'), 22 | }; 23 | -------------------------------------------------------------------------------- /changelog/5.1.0-rc.1/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Graylog2/graylog-plugin-collector/19ef018fbf1dc21b952971e40c6bf8f23ec5dd39/changelog/5.1.0-rc.1/.gitkeep -------------------------------------------------------------------------------- /changelog/unreleased/.gitkeep: -------------------------------------------------------------------------------- 1 | # Keep the directory in Git -------------------------------------------------------------------------------- /jenkins.groovy: -------------------------------------------------------------------------------- 1 | @Library('ci-pipeline-shared') _ 2 | 3 | buildSnapshot(jdk_version: '17') 4 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "CollectorPlugin", 3 | "version": "5.2.0-SNAPSHOT", 4 | "description": "", 5 | "repository": { 6 | "type": "git", 7 | "url": "Graylog2/graylog-plugin-collector" 8 | }, 9 | "scripts": { 10 | "build": "webpack" 11 | }, 12 | "keywords": [ 13 | "graylog" 14 | ], 15 | "author": "Graylog, Inc. ", 16 | "license": "SSPL-1.0", 17 | "dependencies": { 18 | "buffer": "^6.0.3", 19 | "immutable": "^3.7.5", 20 | "semver": "^7.3.8", 21 | "urijs": "^1.19.10" 22 | }, 23 | "devDependencies": { 24 | "graylog-web-plugin": "file:../graylog2-server/graylog2-web-interface/packages/graylog-web-plugin" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/deb/control/control: -------------------------------------------------------------------------------- 1 | Package: [[name]] 2 | Version: [[version]] 3 | Architecture: all 4 | Maintainer: Marius Sturm 5 | Section: web 6 | Priority: optional 7 | Depends: graylog-server | graylog-radio 8 | Description: [[description]] 9 | -------------------------------------------------------------------------------- /src/main/java/org/graylog/plugins/collector/CollectorMetaData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | package org.graylog.plugins.collector; 18 | 19 | import org.graylog2.plugin.PluginMetaData; 20 | import org.graylog2.plugin.ServerStatus; 21 | import org.graylog2.plugin.Version; 22 | 23 | import java.net.URI; 24 | import java.util.EnumSet; 25 | import java.util.Set; 26 | 27 | public class CollectorMetaData implements PluginMetaData { 28 | private static final String PLUGIN_PROPERTIES = "org.graylog.plugins.graylog-plugin-collector/graylog-plugin.properties"; 29 | 30 | @Override 31 | public String getUniqueId() { 32 | return "org.graylog.plugins.collector.CollectorPlugin"; 33 | } 34 | 35 | @Override 36 | public String getName() { 37 | return "Collector"; 38 | } 39 | 40 | @Override 41 | public String getAuthor() { 42 | return "Graylog, Inc."; 43 | } 44 | 45 | @Override 46 | public URI getURL() { 47 | return URI.create("http://docs.graylog.org/en/latest/pages/collector_sidecar.html"); 48 | } 49 | 50 | @Override 51 | public Version getVersion() { 52 | return Version.fromPluginProperties(this.getClass(), PLUGIN_PROPERTIES, "version", Version.from(0, 0, 0, "unknown")); 53 | } 54 | 55 | @Override 56 | public String getDescription() { 57 | return "Collectors plugin"; 58 | } 59 | 60 | @Override 61 | public Version getRequiredVersion() { 62 | return Version.fromPluginProperties(this.getClass(), PLUGIN_PROPERTIES, "graylog.version", Version.CURRENT_CLASSPATH); 63 | } 64 | 65 | @Override 66 | public Set getRequiredCapabilities() { 67 | return EnumSet.of(ServerStatus.Capability.SERVER); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/org/graylog/plugins/collector/CollectorModule.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | package org.graylog.plugins.collector; 18 | 19 | import com.google.common.base.Supplier; 20 | import com.google.common.collect.ImmutableSet; 21 | import com.google.inject.Scopes; 22 | import com.google.inject.TypeLiteral; 23 | import org.graylog.plugins.collector.audit.CollectorAuditEventTypes; 24 | import org.graylog.plugins.collector.collectors.CollectorService; 25 | import org.graylog.plugins.collector.collectors.CollectorServiceImpl; 26 | import org.graylog.plugins.collector.collectors.rest.CollectorResource; 27 | import org.graylog.plugins.collector.common.CollectorPluginConfiguration; 28 | import org.graylog.plugins.collector.configurations.CollectorConfigurationService; 29 | import org.graylog.plugins.collector.configurations.rest.ConfigurationEtagService; 30 | import org.graylog.plugins.collector.configurations.rest.resources.CollectorConfigurationResource; 31 | import org.graylog.plugins.collector.periodical.PurgeExpiredCollectorsThread; 32 | import org.graylog.plugins.collector.permissions.CollectorRestPermissions; 33 | import org.graylog.plugins.collector.system.CollectorSystemConfiguration; 34 | import org.graylog.plugins.collector.system.CollectorSystemConfigurationSupplier; 35 | import org.graylog2.plugin.PluginConfigBean; 36 | import org.graylog2.plugin.PluginModule; 37 | 38 | import java.util.Set; 39 | 40 | public class CollectorModule extends PluginModule { 41 | @Override 42 | public Set getConfigBeans() { 43 | return ImmutableSet.of( 44 | new CollectorPluginConfiguration() 45 | ); 46 | } 47 | 48 | @Override 49 | protected void configure() { 50 | bind(CollectorService.class).to(CollectorServiceImpl.class); 51 | bind(CollectorConfigurationService.class).asEagerSingleton(); 52 | bind(new TypeLiteral>(){}).to(CollectorSystemConfigurationSupplier.class); 53 | 54 | addPeriodical(PurgeExpiredCollectorsThread.class); 55 | addRestResource(CollectorResource.class); 56 | addRestResource(CollectorConfigurationResource.class); 57 | addPermissions(CollectorRestPermissions.class); 58 | 59 | addAuditEventTypes(CollectorAuditEventTypes.class); 60 | 61 | serviceBinder().addBinding().to(ConfigurationEtagService.class).in(Scopes.SINGLETON); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/org/graylog/plugins/collector/CollectorPlugin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | package org.graylog.plugins.collector; 18 | 19 | import org.graylog2.plugin.Plugin; 20 | import org.graylog2.plugin.PluginMetaData; 21 | import org.graylog2.plugin.PluginModule; 22 | 23 | import java.util.Collection; 24 | import java.util.Collections; 25 | 26 | /** 27 | * Implement the Plugin interface here. 28 | */ 29 | public class CollectorPlugin implements Plugin { 30 | @Override 31 | public PluginMetaData metadata() { 32 | return new CollectorMetaData(); 33 | } 34 | 35 | @Override 36 | public Collection modules() { 37 | return Collections.singleton(new CollectorModule()); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/org/graylog/plugins/collector/audit/CollectorAuditEventTypes.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | package org.graylog.plugins.collector.audit; 18 | 19 | import com.google.common.collect.ImmutableSet; 20 | import org.graylog2.audit.PluginAuditEventTypes; 21 | 22 | import java.util.Set; 23 | 24 | public class CollectorAuditEventTypes implements PluginAuditEventTypes { 25 | private static final String NAMESPACE = "collector:"; 26 | 27 | public static final String ACTION_UPDATE = NAMESPACE + "action:update"; 28 | 29 | public static final String CONFIGURATION_CREATE = NAMESPACE + "configuration:create"; 30 | public static final String CONFIGURATION_UPDATE = NAMESPACE + "configuration:update"; 31 | public static final String CONFIGURATION_DELETE = NAMESPACE + "configuration:delete"; 32 | public static final String CONFIGURATION_CLONE = NAMESPACE + "configuration:clone"; 33 | 34 | public static final String TAGS_UPDATE = NAMESPACE + "tags:update"; 35 | 36 | public static final String INPUT_CREATE = NAMESPACE + "input:create"; 37 | public static final String INPUT_UPDATE = NAMESPACE + "input:update"; 38 | public static final String INPUT_DELETE = NAMESPACE + "input:delete"; 39 | public static final String INPUT_CLONE = NAMESPACE + "input:clone"; 40 | 41 | public static final String OUTPUT_CREATE = NAMESPACE + "output:create"; 42 | public static final String OUTPUT_UPDATE = NAMESPACE + "output:update"; 43 | public static final String OUTPUT_DELETE = NAMESPACE + "output:delete"; 44 | public static final String OUTPUT_CLONE = NAMESPACE + "output:clone"; 45 | 46 | public static final String SNIPPET_CREATE = NAMESPACE + "snippet:create"; 47 | public static final String SNIPPET_UPDATE = NAMESPACE + "snippet:update"; 48 | public static final String SNIPPET_DELETE = NAMESPACE + "snippet:delete"; 49 | public static final String SNIPPET_CLONE = NAMESPACE + "snippet:clone"; 50 | 51 | 52 | private static final Set EVENT_TYPES = ImmutableSet.builder() 53 | .add(ACTION_UPDATE) 54 | .add(CONFIGURATION_CREATE) 55 | .add(CONFIGURATION_UPDATE) 56 | .add(CONFIGURATION_DELETE) 57 | .add(CONFIGURATION_CLONE) 58 | .add(TAGS_UPDATE) 59 | .add(INPUT_CREATE) 60 | .add(INPUT_UPDATE) 61 | .add(INPUT_DELETE) 62 | .add(INPUT_CLONE) 63 | .add(OUTPUT_CREATE) 64 | .add(OUTPUT_UPDATE) 65 | .add(OUTPUT_DELETE) 66 | .add(OUTPUT_CLONE) 67 | .add(SNIPPET_CREATE) 68 | .add(SNIPPET_UPDATE) 69 | .add(SNIPPET_DELETE) 70 | .add(SNIPPET_CLONE) 71 | .build(); 72 | 73 | @Override 74 | public Set auditEventTypes() { 75 | return EVENT_TYPES; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/main/java/org/graylog/plugins/collector/collectors/Collector.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | package org.graylog.plugins.collector.collectors; 18 | 19 | import com.google.common.base.Function; 20 | import org.graylog.plugins.collector.collectors.rest.models.responses.CollectorSummary; 21 | import org.joda.time.DateTime; 22 | 23 | import javax.validation.Valid; 24 | import javax.validation.constraints.NotNull; 25 | import javax.validation.constraints.Size; 26 | 27 | public interface Collector { 28 | @NotNull 29 | @Size(min = 1) 30 | String getId(); 31 | 32 | @NotNull 33 | @Size(min = 1) 34 | String getNodeId(); 35 | 36 | @NotNull 37 | String getCollectorVersion(); 38 | 39 | @NotNull 40 | DateTime getLastSeen(); 41 | 42 | @NotNull 43 | @Valid 44 | CollectorNodeDetails getNodeDetails(); 45 | 46 | CollectorSummary toSummary(Function isActiveFunction); 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/org/graylog/plugins/collector/collectors/CollectorActions.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | package org.graylog.plugins.collector.collectors; 18 | 19 | import com.fasterxml.jackson.annotation.JsonAutoDetect; 20 | import com.fasterxml.jackson.annotation.JsonCreator; 21 | import com.fasterxml.jackson.annotation.JsonProperty; 22 | import com.google.auto.value.AutoValue; 23 | import org.graylog.plugins.collector.collectors.rest.models.CollectorAction; 24 | import org.graylog2.database.DbEntity; 25 | import org.hibernate.validator.constraints.NotEmpty; 26 | import org.joda.time.DateTime; 27 | import org.mongojack.Id; 28 | import org.mongojack.ObjectId; 29 | 30 | import javax.annotation.Nullable; 31 | import java.util.List; 32 | 33 | import static org.graylog.plugins.collector.permissions.CollectorRestPermissions.COLLECTORS_READ; 34 | import static org.graylog2.database.DbEntity.NO_TITLE; 35 | 36 | @AutoValue 37 | @JsonAutoDetect 38 | @DbEntity(collection = "collector_actions", 39 | titleField = NO_TITLE, 40 | readPermission = COLLECTORS_READ) 41 | public abstract class CollectorActions { 42 | 43 | @JsonProperty("id") 44 | @Nullable 45 | @Id 46 | @ObjectId 47 | public abstract String getId(); 48 | 49 | @JsonProperty("collector_id") 50 | public abstract String getCollectorId(); 51 | 52 | @JsonProperty("created") 53 | public abstract DateTime getCreated(); 54 | 55 | @JsonProperty("action") 56 | public abstract List getAction(); 57 | 58 | @JsonCreator 59 | public static CollectorActions create(@JsonProperty("id") @Id @ObjectId String id, 60 | @JsonProperty("collector_id") String collectorId, 61 | @JsonProperty("created") DateTime created, 62 | @JsonProperty("action") List action) { 63 | return new AutoValue_CollectorActions(id, collectorId, created, action); 64 | } 65 | 66 | public static CollectorActions create(@NotEmpty String collector_id, 67 | @NotEmpty DateTime created, 68 | @NotEmpty List action) { 69 | return create(new org.bson.types.ObjectId().toHexString(), collector_id, created, action); 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/org/graylog/plugins/collector/collectors/CollectorImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | package org.graylog.plugins.collector.collectors; 18 | 19 | import com.fasterxml.jackson.annotation.JsonAutoDetect; 20 | import com.fasterxml.jackson.annotation.JsonCreator; 21 | import com.fasterxml.jackson.annotation.JsonProperty; 22 | import com.google.auto.value.AutoValue; 23 | import com.google.common.base.Function; 24 | import org.graylog.plugins.collector.collectors.rest.models.responses.CollectorSummary; 25 | import org.graylog2.database.DbEntity; 26 | import org.joda.time.DateTime; 27 | 28 | import static org.graylog.plugins.collector.permissions.CollectorRestPermissions.COLLECTORS_READ; 29 | import static org.graylog2.database.DbEntity.NO_TITLE; 30 | 31 | @AutoValue 32 | @JsonAutoDetect 33 | @DbEntity(collection = "collectors", 34 | titleField = NO_TITLE, 35 | readPermission = COLLECTORS_READ) 36 | public abstract class CollectorImpl implements Collector { 37 | 38 | @JsonProperty("id") 39 | @Override 40 | public abstract String getId(); 41 | 42 | @JsonProperty("node_id") 43 | @Override 44 | public abstract String getNodeId(); 45 | 46 | @Override 47 | @JsonProperty("node_details") 48 | public abstract CollectorNodeDetails getNodeDetails(); 49 | 50 | @Override 51 | @JsonProperty("collector_version") 52 | public abstract String getCollectorVersion(); 53 | 54 | @Override 55 | public CollectorSummary toSummary(Function isActiveFunction) { 56 | final Boolean isActive = isActiveFunction.apply(this); 57 | return CollectorSummary.create(getId(), getNodeId(), getNodeDetails().toSummary(), 58 | getLastSeen(), getCollectorVersion(), isActive != null && isActive); 59 | } 60 | 61 | @JsonProperty("last_seen") 62 | @Override 63 | public abstract DateTime getLastSeen(); 64 | 65 | @JsonCreator 66 | public static CollectorImpl create(@JsonProperty("_id") String objectId, 67 | @JsonProperty("id") String id, 68 | @JsonProperty("node_id") String nodeId, 69 | @JsonProperty("node_details") CollectorNodeDetails collectorNodeDetails, 70 | @JsonProperty("collector_version") String collectorVersion, 71 | @JsonProperty("last_seen") DateTime lastSeen) { 72 | return new AutoValue_CollectorImpl(id, nodeId, collectorNodeDetails, collectorVersion, lastSeen); 73 | } 74 | 75 | public static CollectorImpl create(String collectorId, 76 | String nodeId, 77 | String collectorVersion, 78 | CollectorNodeDetails collectorNodeDetails, 79 | DateTime lastSeen) { 80 | return new AutoValue_CollectorImpl(collectorId, 81 | nodeId, 82 | collectorNodeDetails, 83 | collectorVersion, 84 | lastSeen); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/main/java/org/graylog/plugins/collector/collectors/CollectorNodeDetails.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | package org.graylog.plugins.collector.collectors; 18 | 19 | import com.fasterxml.jackson.annotation.JsonAutoDetect; 20 | import com.fasterxml.jackson.annotation.JsonCreator; 21 | import com.fasterxml.jackson.annotation.JsonProperty; 22 | import com.google.auto.value.AutoValue; 23 | import org.graylog.plugins.collector.collectors.rest.models.CollectorLogFile; 24 | import org.graylog.plugins.collector.collectors.rest.models.CollectorMetrics; 25 | import org.graylog.plugins.collector.collectors.rest.models.CollectorNodeDetailsSummary; 26 | import org.graylog.plugins.collector.collectors.rest.models.CollectorStatusList; 27 | 28 | import javax.annotation.Nullable; 29 | import javax.validation.constraints.NotNull; 30 | import javax.validation.constraints.Size; 31 | import java.util.List; 32 | 33 | @AutoValue 34 | @JsonAutoDetect 35 | public abstract class CollectorNodeDetails { 36 | @JsonProperty("operating_system") 37 | @NotNull 38 | @Size(min = 1) 39 | public abstract String operatingSystem(); 40 | 41 | @JsonProperty("tags") 42 | @Nullable 43 | public abstract List tags(); 44 | 45 | @JsonProperty("ip") 46 | @Nullable 47 | public abstract String ip(); 48 | 49 | @JsonProperty("metrics") 50 | @Nullable 51 | public abstract CollectorMetrics metrics(); 52 | 53 | @JsonProperty("log_file_list") 54 | @Nullable 55 | public abstract List logFileList(); 56 | 57 | @JsonProperty("status") 58 | @Nullable 59 | public abstract CollectorStatusList statusList(); 60 | 61 | @JsonCreator 62 | public static CollectorNodeDetails create(@JsonProperty("operating_system") String operatingSystem, 63 | @JsonProperty("tags") @Nullable List tags, 64 | @JsonProperty("ip") @Nullable String ip, 65 | @JsonProperty("metrics") @Nullable CollectorMetrics metrics, 66 | @JsonProperty("log_file_list") @Nullable List logFileList, 67 | @JsonProperty("status") @Nullable CollectorStatusList statusList) { 68 | return new AutoValue_CollectorNodeDetails(operatingSystem, tags, ip, metrics, logFileList, statusList); 69 | } 70 | 71 | public CollectorNodeDetailsSummary toSummary() { 72 | return CollectorNodeDetailsSummary.create(operatingSystem(), tags(), ip(), metrics(), logFileList(), statusList()); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/org/graylog/plugins/collector/collectors/CollectorService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | package org.graylog.plugins.collector.collectors; 18 | 19 | import org.graylog.plugins.collector.collectors.rest.models.CollectorAction; 20 | import org.graylog.plugins.collector.collectors.rest.models.requests.CollectorRegistrationRequest; 21 | import org.joda.time.Period; 22 | 23 | import java.util.List; 24 | 25 | public interface CollectorService { 26 | long count(); 27 | 28 | Collector save(Collector collector); 29 | 30 | CollectorActions saveAction(CollectorActions collectorActions); 31 | 32 | List all(); 33 | 34 | Collector findById(String id); 35 | 36 | CollectorActions findActionByCollector(String collectorId, boolean remove); 37 | 38 | List findByNodeId(String nodeId); 39 | 40 | int destroy(Collector collector); 41 | 42 | int destroyExpired(Period period); 43 | 44 | Collector fromRequest(String collectorId, CollectorRegistrationRequest request, String collectorVersion); 45 | 46 | CollectorActions actionFromRequest(String collectorId, List request); 47 | 48 | CollectorUpload saveUpload(CollectorUpload collectorUpload); 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/org/graylog/plugins/collector/collectors/CollectorUpload.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | package org.graylog.plugins.collector.collectors; 18 | 19 | import com.fasterxml.jackson.annotation.JsonAutoDetect; 20 | import com.fasterxml.jackson.annotation.JsonCreator; 21 | import com.fasterxml.jackson.annotation.JsonProperty; 22 | import com.google.auto.value.AutoValue; 23 | import org.graylog2.database.DbEntity; 24 | import org.joda.time.DateTime; 25 | import org.mongojack.Id; 26 | import org.mongojack.ObjectId; 27 | 28 | import javax.annotation.Nullable; 29 | 30 | import static org.graylog.plugins.collector.collectors.CollectorUpload.FIELD_COLLECTOR_NAME; 31 | import static org.graylog.plugins.collector.permissions.CollectorRestPermissions.COLLECTORS_READ; 32 | 33 | @AutoValue 34 | @JsonAutoDetect 35 | @DbEntity(collection = "collector_uploads", 36 | titleField = FIELD_COLLECTOR_NAME, 37 | readPermission = COLLECTORS_READ) 38 | public abstract class CollectorUpload { 39 | private static final String FIELD_ID = "id"; 40 | private static final String FIELD_COLLECTOR_ID = "collector_id"; 41 | private static final String FIELD_NODE_ID = "node_id"; 42 | public static final String FIELD_COLLECTOR_NAME = "collector_name"; 43 | private static final String FIELD_RENDERED_CONFIGURATION = "rendered_configuration"; 44 | private static final String FIELD_CREATED = "created"; 45 | 46 | @JsonProperty(FIELD_ID) 47 | @Id 48 | @ObjectId 49 | @Nullable 50 | public abstract String id(); 51 | 52 | @JsonProperty(FIELD_COLLECTOR_ID) 53 | public abstract String collectorId(); 54 | 55 | @JsonProperty(FIELD_NODE_ID) 56 | public abstract String nodeId(); 57 | 58 | @JsonProperty(FIELD_COLLECTOR_NAME) 59 | public abstract String collectorName(); 60 | 61 | @JsonProperty(FIELD_RENDERED_CONFIGURATION) 62 | public abstract String renderedConfiguration(); 63 | 64 | @JsonProperty(FIELD_CREATED) 65 | @Nullable 66 | public abstract DateTime created(); 67 | 68 | public static Builder builder() { 69 | return new AutoValue_CollectorUpload.Builder(); 70 | } 71 | 72 | public abstract Builder toBuilder(); 73 | 74 | @AutoValue.Builder 75 | public abstract static class Builder { 76 | public abstract Builder id(String id); 77 | public abstract Builder collectorId(String collectorId); 78 | public abstract Builder nodeId(String nodeId); 79 | public abstract Builder collectorName(String collectorName); 80 | public abstract Builder renderedConfiguration(String renderedConfiguration); 81 | public abstract Builder created(DateTime created); 82 | public abstract CollectorUpload build(); 83 | } 84 | 85 | @JsonCreator 86 | public static CollectorUpload create(@JsonProperty(FIELD_ID) String id, 87 | @JsonProperty(FIELD_COLLECTOR_ID) String collectorId, 88 | @JsonProperty(FIELD_NODE_ID) String nodeId, 89 | @JsonProperty(FIELD_COLLECTOR_NAME) String collectorName, 90 | @JsonProperty(FIELD_RENDERED_CONFIGURATION) String renderedConfiguration, 91 | @JsonProperty(FIELD_CREATED) @Nullable DateTime created) { 92 | return builder() 93 | .id(id) 94 | .collectorId(collectorId) 95 | .nodeId(nodeId) 96 | .collectorName(collectorName) 97 | .renderedConfiguration(renderedConfiguration) 98 | .created(created) 99 | .build(); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/main/java/org/graylog/plugins/collector/collectors/Collectors.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | package org.graylog.plugins.collector.collectors; 18 | 19 | import com.google.common.base.Function; 20 | import com.google.common.collect.Lists; 21 | import org.graylog.plugins.collector.collectors.rest.models.responses.CollectorSummary; 22 | 23 | import java.util.List; 24 | 25 | public class Collectors { 26 | public static List toSummaryList(List collectors, Function isActiveFunction) { 27 | final List collectorSummaries = Lists.newArrayListWithCapacity(collectors.size()); 28 | for (Collector collector : collectors) 29 | collectorSummaries.add(collector.toSummary(isActiveFunction)); 30 | 31 | return collectorSummaries; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/org/graylog/plugins/collector/collectors/rest/models/CollectorAction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | package org.graylog.plugins.collector.collectors.rest.models; 18 | 19 | import com.fasterxml.jackson.annotation.JsonAutoDetect; 20 | import com.fasterxml.jackson.annotation.JsonCreator; 21 | import com.fasterxml.jackson.annotation.JsonProperty; 22 | import com.google.auto.value.AutoValue; 23 | 24 | import java.util.Map; 25 | 26 | @AutoValue 27 | @JsonAutoDetect 28 | public abstract class CollectorAction { 29 | 30 | @JsonProperty("backend") 31 | public abstract String backend(); 32 | 33 | @JsonProperty("properties") 34 | public abstract Map properties(); 35 | 36 | @JsonCreator 37 | public static CollectorAction create(@JsonProperty("backend") String backend, 38 | @JsonProperty("properties") Map properties) { 39 | return new AutoValue_CollectorAction(backend, properties); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/org/graylog/plugins/collector/collectors/rest/models/CollectorLogFile.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | package org.graylog.plugins.collector.collectors.rest.models; 18 | 19 | import com.fasterxml.jackson.annotation.JsonAutoDetect; 20 | import com.fasterxml.jackson.annotation.JsonCreator; 21 | import com.fasterxml.jackson.annotation.JsonProperty; 22 | import com.google.auto.value.AutoValue; 23 | import org.joda.time.DateTime; 24 | 25 | @AutoValue 26 | @JsonAutoDetect 27 | public abstract class CollectorLogFile { 28 | @JsonProperty("path") 29 | public abstract String path(); 30 | 31 | @JsonProperty("mod_time") 32 | public abstract DateTime modTime(); 33 | 34 | @JsonProperty("size") 35 | public abstract long size(); 36 | 37 | @JsonProperty("is_dir") 38 | public abstract boolean isDir(); 39 | 40 | @JsonCreator 41 | public static CollectorLogFile create(@JsonProperty("path") String path, 42 | @JsonProperty("mod_time") DateTime modTime, 43 | @JsonProperty("size") long size, 44 | @JsonProperty("is_dir") boolean isDir) { 45 | return new AutoValue_CollectorLogFile(path, modTime, size, isDir); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/org/graylog/plugins/collector/collectors/rest/models/CollectorMetrics.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | package org.graylog.plugins.collector.collectors.rest.models; 18 | 19 | import com.fasterxml.jackson.annotation.JsonAutoDetect; 20 | import com.fasterxml.jackson.annotation.JsonCreator; 21 | import com.fasterxml.jackson.annotation.JsonProperty; 22 | import com.google.auto.value.AutoValue; 23 | 24 | import javax.annotation.Nullable; 25 | import java.util.List; 26 | 27 | @AutoValue 28 | @JsonAutoDetect 29 | public abstract class CollectorMetrics { 30 | @JsonProperty("disks_75") 31 | @Nullable 32 | public abstract List disks75(); 33 | 34 | @JsonProperty("cpu_idle") 35 | @Nullable 36 | public abstract Float cpuIdle(); 37 | 38 | @JsonProperty("load_1") 39 | @Nullable 40 | public abstract Float load1(); 41 | 42 | @JsonCreator 43 | public static CollectorMetrics create(@JsonProperty("disks_75") @Nullable List disks75, 44 | @JsonProperty("cpu_idle") @Nullable Float cpuIdle, 45 | @JsonProperty("load_1") @Nullable Float load1) { 46 | return new AutoValue_CollectorMetrics(disks75, cpuIdle, load1); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/org/graylog/plugins/collector/collectors/rest/models/CollectorNodeDetailsSummary.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | package org.graylog.plugins.collector.collectors.rest.models; 18 | 19 | import com.fasterxml.jackson.annotation.JsonAutoDetect; 20 | import com.fasterxml.jackson.annotation.JsonCreator; 21 | import com.fasterxml.jackson.annotation.JsonProperty; 22 | import com.google.auto.value.AutoValue; 23 | 24 | import javax.annotation.Nullable; 25 | import javax.validation.constraints.NotNull; 26 | import javax.validation.constraints.Size; 27 | import java.util.List; 28 | 29 | @AutoValue 30 | @JsonAutoDetect 31 | public abstract class CollectorNodeDetailsSummary { 32 | 33 | @JsonProperty("operating_system") 34 | @NotNull 35 | @Size(min = 1) 36 | public abstract String operatingSystem(); 37 | 38 | @JsonProperty("tags") 39 | @Nullable 40 | public abstract List tags(); 41 | 42 | @JsonProperty("ip") 43 | @Nullable 44 | public abstract String ip(); 45 | 46 | 47 | @JsonProperty("metrics") 48 | @Nullable 49 | public abstract CollectorMetrics metrics(); 50 | 51 | @JsonProperty("log_file_list") 52 | @Nullable 53 | public abstract List logFileList(); 54 | 55 | @JsonProperty("status") 56 | @Nullable 57 | public abstract CollectorStatusList statusList(); 58 | 59 | @JsonCreator 60 | public static CollectorNodeDetailsSummary create(@JsonProperty("operating_system") String operatingSystem, 61 | @JsonProperty("tags") @Nullable List tags, 62 | @JsonProperty("ip") @Nullable String ip, 63 | @JsonProperty("metrics") @Nullable CollectorMetrics metrics, 64 | @JsonProperty("log_file_list") @Nullable List logFileList, 65 | @JsonProperty("status") @Nullable CollectorStatusList statusList) { 66 | return new AutoValue_CollectorNodeDetailsSummary(operatingSystem, tags, ip, metrics, logFileList, statusList); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/org/graylog/plugins/collector/collectors/rest/models/CollectorStatus.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | package org.graylog.plugins.collector.collectors.rest.models; 18 | 19 | import com.fasterxml.jackson.annotation.JsonAutoDetect; 20 | import com.fasterxml.jackson.annotation.JsonCreator; 21 | import com.fasterxml.jackson.annotation.JsonProperty; 22 | import com.google.auto.value.AutoValue; 23 | 24 | @AutoValue 25 | @JsonAutoDetect 26 | public abstract class CollectorStatus { 27 | @JsonProperty("status") 28 | public abstract int status(); 29 | 30 | @JsonProperty("message") 31 | public abstract String message(); 32 | 33 | @JsonCreator 34 | public static CollectorStatus create(@JsonProperty("status") int status, 35 | @JsonProperty("message") String message) { 36 | return new AutoValue_CollectorStatus(status, message); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/org/graylog/plugins/collector/collectors/rest/models/CollectorStatusList.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | package org.graylog.plugins.collector.collectors.rest.models; 18 | 19 | import com.fasterxml.jackson.annotation.JsonAutoDetect; 20 | import com.fasterxml.jackson.annotation.JsonCreator; 21 | import com.fasterxml.jackson.annotation.JsonProperty; 22 | import com.google.auto.value.AutoValue; 23 | 24 | import java.util.HashMap; 25 | 26 | @AutoValue 27 | @JsonAutoDetect 28 | public abstract class CollectorStatusList { 29 | @JsonProperty("status") 30 | public abstract int status(); 31 | 32 | @JsonProperty("message") 33 | public abstract String message(); 34 | 35 | @JsonProperty("backends") 36 | public abstract HashMap backends(); 37 | 38 | @JsonCreator 39 | public static CollectorStatusList create(@JsonProperty("status") int status, 40 | @JsonProperty("message") String message, 41 | @JsonProperty("backends") HashMap backends) { 42 | return new AutoValue_CollectorStatusList(status, message, backends); 43 | }} 44 | -------------------------------------------------------------------------------- /src/main/java/org/graylog/plugins/collector/collectors/rest/models/requests/CollectorRegistrationRequest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | package org.graylog.plugins.collector.collectors.rest.models.requests; 18 | 19 | import com.fasterxml.jackson.annotation.JsonAutoDetect; 20 | import com.fasterxml.jackson.annotation.JsonCreator; 21 | import com.fasterxml.jackson.annotation.JsonProperty; 22 | import com.google.auto.value.AutoValue; 23 | import org.graylog.plugins.collector.collectors.rest.models.CollectorNodeDetailsSummary; 24 | 25 | import javax.validation.Valid; 26 | import javax.validation.constraints.NotNull; 27 | import javax.validation.constraints.Size; 28 | 29 | @AutoValue 30 | @JsonAutoDetect 31 | public abstract class CollectorRegistrationRequest { 32 | @JsonProperty("node_id") 33 | @NotNull 34 | @Size(min = 1) 35 | public abstract String nodeId(); 36 | 37 | @JsonProperty("node_details") 38 | public abstract CollectorNodeDetailsSummary nodeDetails(); 39 | 40 | @JsonCreator 41 | public static CollectorRegistrationRequest create(@JsonProperty("node_id") String nodeId, 42 | @JsonProperty("node_details") @Valid CollectorNodeDetailsSummary nodeDetails) { 43 | return new AutoValue_CollectorRegistrationRequest(nodeId, nodeDetails); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/org/graylog/plugins/collector/collectors/rest/models/responses/CollectorList.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | package org.graylog.plugins.collector.collectors.rest.models.responses; 18 | 19 | import com.fasterxml.jackson.annotation.JsonAutoDetect; 20 | import com.fasterxml.jackson.annotation.JsonCreator; 21 | import com.fasterxml.jackson.annotation.JsonProperty; 22 | import com.google.auto.value.AutoValue; 23 | 24 | import java.util.List; 25 | 26 | @AutoValue 27 | @JsonAutoDetect 28 | public abstract class CollectorList { 29 | @JsonProperty 30 | public abstract List collectors(); 31 | 32 | @JsonCreator 33 | public static CollectorList create(@JsonProperty("collectors") List collectors) { 34 | return new AutoValue_CollectorList(collectors); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/org/graylog/plugins/collector/collectors/rest/models/responses/CollectorRegistrationAction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | package org.graylog.plugins.collector.collectors.rest.models.responses; 18 | 19 | import com.fasterxml.jackson.annotation.JsonAutoDetect; 20 | import com.fasterxml.jackson.annotation.JsonCreator; 21 | import com.fasterxml.jackson.annotation.JsonProperty; 22 | import com.google.auto.value.AutoValue; 23 | 24 | @AutoValue 25 | @JsonAutoDetect 26 | public abstract class CollectorRegistrationAction { 27 | @JsonProperty 28 | public abstract boolean restart(); 29 | 30 | @JsonCreator 31 | public static CollectorRegistrationAction create(@JsonProperty("restart") boolean restart) { 32 | return new AutoValue_CollectorRegistrationAction(restart); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/org/graylog/plugins/collector/collectors/rest/models/responses/CollectorRegistrationConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | package org.graylog.plugins.collector.collectors.rest.models.responses; 18 | 19 | import com.fasterxml.jackson.annotation.JsonAutoDetect; 20 | import com.fasterxml.jackson.annotation.JsonCreator; 21 | import com.fasterxml.jackson.annotation.JsonProperty; 22 | import com.google.auto.value.AutoValue; 23 | 24 | @AutoValue 25 | @JsonAutoDetect 26 | public abstract class CollectorRegistrationConfiguration { 27 | @JsonProperty 28 | public abstract long updateInterval(); 29 | 30 | @JsonProperty 31 | public abstract boolean sendStatus(); 32 | 33 | @JsonCreator 34 | public static CollectorRegistrationConfiguration create(@JsonProperty("update_interval") long updateInterval, 35 | @JsonProperty("send_status") boolean sendStatus) { 36 | return new AutoValue_CollectorRegistrationConfiguration(updateInterval, sendStatus); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/org/graylog/plugins/collector/collectors/rest/models/responses/CollectorRegistrationResponse.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | package org.graylog.plugins.collector.collectors.rest.models.responses; 18 | 19 | 20 | import com.fasterxml.jackson.annotation.JsonAutoDetect; 21 | import com.fasterxml.jackson.annotation.JsonCreator; 22 | import com.fasterxml.jackson.annotation.JsonProperty; 23 | import com.google.auto.value.AutoValue; 24 | import org.graylog.plugins.collector.collectors.rest.models.CollectorAction; 25 | 26 | import javax.annotation.Nullable; 27 | import java.util.List; 28 | 29 | @AutoValue 30 | @JsonAutoDetect 31 | public abstract class CollectorRegistrationResponse { 32 | @JsonProperty("configuration") 33 | public abstract CollectorRegistrationConfiguration collectorRegistrationConfiguration(); 34 | 35 | @JsonProperty("configuration_override") 36 | public abstract boolean configurationOverride(); 37 | 38 | @JsonProperty("actions") 39 | @Nullable 40 | public abstract List actions(); 41 | 42 | @JsonCreator 43 | public static CollectorRegistrationResponse create(@JsonProperty("configuration") CollectorRegistrationConfiguration collectorRegistrationConfiguration, 44 | @JsonProperty("configuration_override") boolean configurationOverride, 45 | @JsonProperty("actions") @Nullable List actions) { 46 | return new AutoValue_CollectorRegistrationResponse(collectorRegistrationConfiguration, configurationOverride, actions); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/org/graylog/plugins/collector/collectors/rest/models/responses/CollectorSummary.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | package org.graylog.plugins.collector.collectors.rest.models.responses; 18 | 19 | import com.fasterxml.jackson.annotation.JsonAutoDetect; 20 | import com.fasterxml.jackson.annotation.JsonCreator; 21 | import com.fasterxml.jackson.annotation.JsonProperty; 22 | import com.google.auto.value.AutoValue; 23 | import org.graylog.plugins.collector.collectors.rest.models.CollectorNodeDetailsSummary; 24 | import org.joda.time.DateTime; 25 | 26 | @AutoValue 27 | @JsonAutoDetect 28 | public abstract class CollectorSummary { 29 | 30 | @JsonProperty 31 | public abstract String id(); 32 | 33 | @JsonProperty("node_id") 34 | public abstract String nodeId(); 35 | 36 | @JsonProperty("node_details") 37 | public abstract CollectorNodeDetailsSummary nodeDetails(); 38 | 39 | @JsonProperty("last_seen") 40 | public abstract DateTime lastSeen(); 41 | 42 | @JsonProperty("collector_version") 43 | public abstract String collectorVersion(); 44 | 45 | @JsonProperty 46 | public abstract boolean active(); 47 | 48 | @JsonCreator 49 | public static CollectorSummary create(@JsonProperty("id") String id, 50 | @JsonProperty("node_id") String nodeId, 51 | @JsonProperty("node_details") CollectorNodeDetailsSummary nodeDetails, 52 | @JsonProperty("last_seen") DateTime lastSeen, 53 | @JsonProperty("collector_version") String collectorVersion, 54 | @JsonProperty("active") boolean active) { 55 | return new AutoValue_CollectorSummary(id, nodeId, nodeDetails, lastSeen, collectorVersion, active); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/org/graylog/plugins/collector/common/CollectorPluginConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | package org.graylog.plugins.collector.common; 18 | 19 | import com.github.joschi.jadconfig.Parameter; 20 | import com.github.joschi.jadconfig.util.Duration; 21 | import com.github.joschi.jadconfig.validators.PositiveDurationValidator; 22 | import com.github.joschi.jadconfig.validators.PositiveIntegerValidator; 23 | import org.graylog2.plugin.PluginConfigBean; 24 | 25 | public class CollectorPluginConfiguration implements PluginConfigBean { 26 | private static final String PREFIX = "collector_sidecar_"; 27 | 28 | @Parameter(value = PREFIX + "cache_time", validator = PositiveDurationValidator.class) 29 | private Duration cacheTime = Duration.hours(1L); 30 | 31 | public Duration getCacheTime() { 32 | return cacheTime; 33 | } 34 | 35 | @Parameter(value = PREFIX + "cache_max_size", validator = PositiveIntegerValidator.class) 36 | private int cacheMaxSize = 100; 37 | 38 | public int getCacheMaxSize() { 39 | return cacheMaxSize; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/org/graylog/plugins/collector/configurations/rest/CollectorConfigurationEtagInvalidation.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | package org.graylog.plugins.collector.configurations.rest; 18 | 19 | import com.fasterxml.jackson.annotation.JsonCreator; 20 | import com.fasterxml.jackson.annotation.JsonProperty; 21 | import com.google.auto.value.AutoValue; 22 | 23 | @AutoValue 24 | public abstract class CollectorConfigurationEtagInvalidation { 25 | 26 | @JsonProperty("etag") 27 | public abstract String etag(); 28 | 29 | @JsonCreator 30 | public static CollectorConfigurationEtagInvalidation etag(@JsonProperty("etag") String etag) { 31 | return new AutoValue_CollectorConfigurationEtagInvalidation(etag); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/org/graylog/plugins/collector/configurations/rest/ConfigurationEtagService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | package org.graylog.plugins.collector.configurations.rest; 18 | 19 | import com.codahale.metrics.MetricRegistry; 20 | import com.github.joschi.jadconfig.util.Duration; 21 | import com.google.common.cache.Cache; 22 | import com.google.common.cache.CacheBuilder; 23 | import com.google.common.eventbus.EventBus; 24 | import com.google.common.eventbus.Subscribe; 25 | import com.google.common.util.concurrent.AbstractIdleService; 26 | import org.graylog.plugins.collector.common.CollectorPluginConfiguration; 27 | import org.graylog.plugins.collector.configurations.CollectorConfigurationService; 28 | import org.graylog2.events.ClusterEventBus; 29 | import org.graylog2.metrics.CacheStatsSet; 30 | import org.graylog2.shared.metrics.MetricUtils; 31 | import org.slf4j.Logger; 32 | import org.slf4j.LoggerFactory; 33 | 34 | import javax.inject.Inject; 35 | import javax.inject.Singleton; 36 | 37 | import static com.codahale.metrics.MetricRegistry.name; 38 | 39 | @Singleton 40 | public class ConfigurationEtagService extends AbstractIdleService { 41 | private static final Logger LOG = LoggerFactory.getLogger(ConfigurationEtagService.class); 42 | 43 | private final Cache cache; 44 | private MetricRegistry metricRegistry; 45 | private EventBus eventBus; 46 | private ClusterEventBus clusterEventBus; 47 | 48 | @Inject 49 | public ConfigurationEtagService(CollectorPluginConfiguration pluginConfiguration, 50 | MetricRegistry metricRegistry, 51 | EventBus eventBus, 52 | ClusterEventBus clusterEventBus) { 53 | this.metricRegistry = metricRegistry; 54 | this.eventBus = eventBus; 55 | this.clusterEventBus = clusterEventBus; 56 | Duration cacheTime = pluginConfiguration.getCacheTime(); 57 | cache = CacheBuilder.newBuilder() 58 | .recordStats() 59 | .expireAfterWrite(cacheTime.getQuantity(), cacheTime.getUnit()) 60 | .maximumSize(pluginConfiguration.getCacheMaxSize()) 61 | .build(); 62 | } 63 | 64 | @Subscribe 65 | public void handleEtagInvalidation(CollectorConfigurationEtagInvalidation event) { 66 | if (event.etag().equals("")) { 67 | LOG.trace("Invalidating all collector configuration etags"); 68 | cache.invalidateAll(); 69 | } else { 70 | LOG.trace("Invalidating collector configuration etag {}", event.etag()); 71 | cache.invalidate(event.etag()); 72 | } 73 | } 74 | 75 | public boolean isPresent(String etag) { 76 | return cache.getIfPresent(etag) != null; 77 | } 78 | 79 | public void put(String etag) { 80 | cache.put(etag, etag); 81 | } 82 | 83 | public void invalidate(String etag) { 84 | clusterEventBus.post(CollectorConfigurationEtagInvalidation.etag(etag)); 85 | } 86 | 87 | public void invalidateAll() { 88 | cache.invalidateAll(); 89 | clusterEventBus.post(CollectorConfigurationEtagInvalidation.etag("")); 90 | } 91 | 92 | @Override 93 | protected void startUp() throws Exception { 94 | eventBus.register(this); 95 | MetricUtils.safelyRegisterAll(metricRegistry, new CacheStatsSet(name(CollectorConfigurationService.class, "etag-cache"), cache)); 96 | } 97 | 98 | @Override 99 | protected void shutDown() throws Exception { 100 | eventBus.unregister(this); 101 | metricRegistry.removeMatching((name, metric) -> name.startsWith(name(CollectorConfigurationService.class, "etag-cache"))); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /src/main/java/org/graylog/plugins/collector/configurations/rest/models/CollectorConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | package org.graylog.plugins.collector.configurations.rest.models; 18 | 19 | import com.fasterxml.jackson.annotation.JsonCreator; 20 | import com.fasterxml.jackson.annotation.JsonProperty; 21 | import com.google.auto.value.AutoValue; 22 | import org.hibernate.validator.constraints.NotEmpty; 23 | import org.mongojack.Id; 24 | import org.mongojack.ObjectId; 25 | 26 | import javax.annotation.Nullable; 27 | import java.util.List; 28 | 29 | 30 | @AutoValue 31 | public abstract class CollectorConfiguration { 32 | @JsonProperty("id") 33 | @Nullable 34 | @Id 35 | @ObjectId 36 | public abstract String id(); 37 | 38 | @JsonProperty("name") 39 | public abstract String name(); 40 | 41 | @JsonProperty 42 | public abstract List tags(); 43 | 44 | @JsonProperty 45 | public abstract List inputs(); 46 | 47 | @JsonProperty 48 | public abstract List outputs(); 49 | 50 | @JsonProperty 51 | public abstract List snippets(); 52 | 53 | @JsonCreator 54 | public static CollectorConfiguration create(@JsonProperty("id") @Id @ObjectId String id, 55 | @JsonProperty("name") String name, 56 | @JsonProperty("tags") List tags, 57 | @JsonProperty("inputs") List inputs, 58 | @JsonProperty("outputs") List outputs, 59 | @JsonProperty("snippets") List snippets) { 60 | return builder() 61 | .id(id) 62 | .name(name) 63 | .tags(tags) 64 | .inputs(inputs) 65 | .outputs(outputs) 66 | .snippets(snippets) 67 | .build(); 68 | } 69 | 70 | public static CollectorConfiguration create(@NotEmpty String name, 71 | @NotEmpty List tags, 72 | @NotEmpty List inputs, 73 | @NotEmpty List outputs, 74 | @NotEmpty List snippets) { 75 | return create(new org.bson.types.ObjectId().toHexString(), name, tags, inputs, outputs, snippets); 76 | } 77 | 78 | public void mergeWith(CollectorConfiguration collectorConfiguration) { 79 | if (collectorConfiguration.inputs() != null) this.inputs().addAll(collectorConfiguration.inputs()); 80 | if (collectorConfiguration.outputs() != null) this.outputs().addAll(collectorConfiguration.outputs()); 81 | if (collectorConfiguration.snippets() != null) this.snippets().addAll(collectorConfiguration.snippets()); 82 | } 83 | 84 | public static Builder builder() { 85 | return new AutoValue_CollectorConfiguration.Builder(); 86 | } 87 | 88 | public abstract Builder toBuilder(); 89 | 90 | @AutoValue.Builder 91 | public abstract static class Builder { 92 | public abstract CollectorConfiguration build(); 93 | 94 | public abstract Builder id(String id); 95 | 96 | public abstract Builder name(String name); 97 | 98 | public abstract Builder tags(List tags); 99 | 100 | public abstract Builder inputs(List inputs); 101 | 102 | public abstract Builder outputs(List outputs); 103 | 104 | public abstract Builder snippets(List snippets); 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /src/main/java/org/graylog/plugins/collector/configurations/rest/models/CollectorConfigurationSnippet.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | package org.graylog.plugins.collector.configurations.rest.models; 18 | 19 | import com.fasterxml.jackson.annotation.JsonCreator; 20 | import com.fasterxml.jackson.annotation.JsonProperty; 21 | import com.google.auto.value.AutoValue; 22 | import org.hibernate.validator.constraints.NotEmpty; 23 | import org.mongojack.ObjectId; 24 | 25 | @AutoValue 26 | public abstract class CollectorConfigurationSnippet { 27 | @JsonProperty("snippet_id") 28 | @ObjectId 29 | public abstract String snippetId(); 30 | 31 | @JsonProperty 32 | public abstract String backend(); 33 | 34 | @JsonProperty 35 | public abstract String name(); 36 | 37 | @JsonProperty 38 | public abstract String snippet(); 39 | 40 | @JsonCreator 41 | public static CollectorConfigurationSnippet create(@JsonProperty("snippet_id") String snippetId, 42 | @JsonProperty("backend") String backend, 43 | @JsonProperty("name") String name, 44 | @JsonProperty("snippet") String snippet) { 45 | if (snippetId == null) { 46 | snippetId = org.bson.types.ObjectId.get().toString(); 47 | } 48 | return new AutoValue_CollectorConfigurationSnippet(snippetId, backend, name, snippet); 49 | } 50 | 51 | public static CollectorConfigurationSnippet create(@NotEmpty String backend, 52 | @NotEmpty String name, 53 | @NotEmpty String snippet) { 54 | return create(org.bson.types.ObjectId.get().toString(), backend, name, snippet); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/org/graylog/plugins/collector/configurations/rest/models/CollectorConfigurationSummary.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | package org.graylog.plugins.collector.configurations.rest.models; 18 | 19 | import com.fasterxml.jackson.annotation.JsonCreator; 20 | import com.fasterxml.jackson.annotation.JsonProperty; 21 | import com.google.auto.value.AutoValue; 22 | import org.mongojack.Id; 23 | import org.mongojack.ObjectId; 24 | 25 | import java.util.List; 26 | 27 | @AutoValue 28 | public abstract class CollectorConfigurationSummary { 29 | @JsonProperty("id") 30 | @Id 31 | @ObjectId 32 | public abstract String id(); 33 | 34 | @JsonProperty("name") 35 | public abstract String name(); 36 | 37 | @JsonProperty("tags") 38 | public abstract List tags(); 39 | 40 | @JsonCreator 41 | public static CollectorConfigurationSummary create(@JsonProperty("id") @Id @ObjectId String id, 42 | @JsonProperty("name") String name, 43 | @JsonProperty("tags") List tags) { 44 | return new AutoValue_CollectorConfigurationSummary(id, name, tags); 45 | } 46 | 47 | } 48 | 49 | -------------------------------------------------------------------------------- /src/main/java/org/graylog/plugins/collector/configurations/rest/models/CollectorInput.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | package org.graylog.plugins.collector.configurations.rest.models; 18 | 19 | import com.fasterxml.jackson.annotation.JsonCreator; 20 | import com.fasterxml.jackson.annotation.JsonProperty; 21 | import com.google.auto.value.AutoValue; 22 | import org.hibernate.validator.constraints.NotEmpty; 23 | import org.mongojack.ObjectId; 24 | 25 | import javax.annotation.Nullable; 26 | import java.util.Map; 27 | 28 | @AutoValue 29 | public abstract class CollectorInput { 30 | @JsonProperty("input_id") 31 | @ObjectId 32 | public abstract String inputId(); 33 | 34 | @JsonProperty 35 | public abstract String backend(); 36 | 37 | @JsonProperty 38 | public abstract String type(); 39 | 40 | @JsonProperty 41 | public abstract String name(); 42 | 43 | @JsonProperty("forward_to") 44 | public abstract String forwardTo(); 45 | 46 | @JsonProperty 47 | @Nullable 48 | public abstract Map properties(); 49 | 50 | @JsonCreator 51 | public static CollectorInput create(@JsonProperty("input_id") String inputId, 52 | @JsonProperty("backend") String backend, 53 | @JsonProperty("type") String type, 54 | @JsonProperty("name") String name, 55 | @JsonProperty("forward_to") String forwardTo, 56 | @JsonProperty("properties") Map properties) { 57 | if (inputId == null) { 58 | inputId = org.bson.types.ObjectId.get().toString(); 59 | } 60 | return new AutoValue_CollectorInput(inputId, backend, type, name, forwardTo, properties); 61 | } 62 | 63 | public static CollectorInput create(@NotEmpty String type, 64 | @NotEmpty String backend, 65 | @NotEmpty String name, 66 | @NotEmpty String forwardTo, 67 | @NotEmpty Map properties) { 68 | return create(org.bson.types.ObjectId.get().toString(), backend, type, name, forwardTo, properties); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/org/graylog/plugins/collector/configurations/rest/models/CollectorOutput.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | package org.graylog.plugins.collector.configurations.rest.models; 18 | 19 | import com.fasterxml.jackson.annotation.JsonCreator; 20 | import com.fasterxml.jackson.annotation.JsonProperty; 21 | import com.google.auto.value.AutoValue; 22 | import org.hibernate.validator.constraints.NotEmpty; 23 | import org.mongojack.ObjectId; 24 | 25 | import javax.annotation.Nullable; 26 | import java.util.Map; 27 | 28 | @AutoValue 29 | public abstract class CollectorOutput { 30 | @JsonProperty("output_id") 31 | @ObjectId 32 | public abstract String outputId(); 33 | 34 | @JsonProperty 35 | public abstract String backend(); 36 | 37 | @JsonProperty 38 | public abstract String type(); 39 | 40 | @JsonProperty 41 | public abstract String name(); 42 | 43 | @JsonProperty 44 | @Nullable 45 | public abstract Map properties(); 46 | 47 | @JsonCreator 48 | public static CollectorOutput create(@JsonProperty("output_id") String outputId, 49 | @JsonProperty("backend") String backend, 50 | @JsonProperty("type") String type, 51 | @JsonProperty("name") String name, 52 | @JsonProperty("properties") Map properties) { 53 | if (outputId == null) { 54 | outputId = org.bson.types.ObjectId.get().toString(); 55 | } 56 | return new AutoValue_CollectorOutput(outputId, backend, type, name, properties); 57 | } 58 | 59 | public static CollectorOutput create(@NotEmpty String backend, 60 | @NotEmpty String type, 61 | @NotEmpty String name, 62 | @NotEmpty Map properties) { 63 | return create(org.bson.types.ObjectId.get().toString(), backend, type, name, properties); 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/org/graylog/plugins/collector/configurations/rest/responses/CollectorConfigurationListResponse.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | package org.graylog.plugins.collector.configurations.rest.responses; 18 | 19 | import com.fasterxml.jackson.annotation.JsonCreator; 20 | import com.fasterxml.jackson.annotation.JsonProperty; 21 | import com.google.auto.value.AutoValue; 22 | import org.graylog.plugins.collector.configurations.rest.models.CollectorConfigurationSummary; 23 | 24 | import java.util.Collection; 25 | 26 | @AutoValue 27 | public abstract class CollectorConfigurationListResponse { 28 | @JsonProperty 29 | public abstract long total(); 30 | 31 | @JsonProperty 32 | public abstract Collection configurations(); 33 | 34 | @JsonCreator 35 | public static CollectorConfigurationListResponse create(@JsonProperty("total") long total, 36 | @JsonProperty("configurations") Collection configurations) { 37 | return new AutoValue_CollectorConfigurationListResponse(total, configurations); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/org/graylog/plugins/collector/configurations/rest/responses/CollectorInputListResponse.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | package org.graylog.plugins.collector.configurations.rest.responses; 18 | 19 | import com.fasterxml.jackson.annotation.JsonCreator; 20 | import com.fasterxml.jackson.annotation.JsonProperty; 21 | import com.google.auto.value.AutoValue; 22 | import org.graylog.plugins.collector.configurations.rest.models.CollectorInput; 23 | 24 | import java.util.Collection; 25 | 26 | @AutoValue 27 | public abstract class CollectorInputListResponse { 28 | @JsonProperty 29 | public abstract long total(); 30 | 31 | @JsonProperty 32 | public abstract Collection inputs(); 33 | 34 | @JsonCreator 35 | public static CollectorInputListResponse create(@JsonProperty("total") long total, 36 | @JsonProperty("inputs") Collection inputs) { 37 | return new AutoValue_CollectorInputListResponse(total, inputs); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/org/graylog/plugins/collector/configurations/rest/responses/CollectorOutputListResponse.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | package org.graylog.plugins.collector.configurations.rest.responses; 18 | 19 | import com.fasterxml.jackson.annotation.JsonCreator; 20 | import com.fasterxml.jackson.annotation.JsonProperty; 21 | import com.google.auto.value.AutoValue; 22 | import org.graylog.plugins.collector.configurations.rest.models.CollectorOutput; 23 | 24 | import java.util.Collection; 25 | 26 | @AutoValue 27 | public abstract class CollectorOutputListResponse { 28 | @JsonProperty 29 | public abstract long total(); 30 | 31 | @JsonProperty 32 | public abstract Collection outputs(); 33 | 34 | @JsonCreator 35 | public static CollectorOutputListResponse create(@JsonProperty("total") long total, 36 | @JsonProperty("outputs") Collection outputs) { 37 | return new AutoValue_CollectorOutputListResponse(total, outputs); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/org/graylog/plugins/collector/configurations/rest/responses/CollectorSnippetListResponse.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | package org.graylog.plugins.collector.configurations.rest.responses; 18 | 19 | import com.fasterxml.jackson.annotation.JsonCreator; 20 | import com.fasterxml.jackson.annotation.JsonProperty; 21 | import com.google.auto.value.AutoValue; 22 | import org.graylog.plugins.collector.configurations.rest.models.CollectorConfigurationSnippet; 23 | 24 | import java.util.Collection; 25 | 26 | @AutoValue 27 | public abstract class CollectorSnippetListResponse { 28 | @JsonProperty 29 | public abstract long total(); 30 | 31 | @JsonProperty 32 | public abstract Collection snippets(); 33 | 34 | @JsonCreator 35 | public static CollectorSnippetListResponse create(@JsonProperty("total") long total, 36 | @JsonProperty("snippets") Collection snippets) { 37 | return new AutoValue_CollectorSnippetListResponse(total, snippets); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/org/graylog/plugins/collector/periodical/PurgeExpiredCollectorsThread.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | package org.graylog.plugins.collector.periodical; 18 | 19 | import com.google.common.base.Supplier; 20 | import org.graylog.plugins.collector.collectors.CollectorService; 21 | import org.graylog.plugins.collector.system.CollectorSystemConfiguration; 22 | import org.graylog2.plugin.periodical.Periodical; 23 | import org.slf4j.Logger; 24 | import org.slf4j.LoggerFactory; 25 | 26 | import javax.inject.Inject; 27 | 28 | public class PurgeExpiredCollectorsThread extends Periodical { 29 | private static final Logger LOG = LoggerFactory.getLogger(PurgeExpiredCollectorsThread.class); 30 | 31 | private final CollectorService collectorService; 32 | private final Supplier configSupplier; 33 | 34 | @Inject 35 | public PurgeExpiredCollectorsThread(CollectorService collectorService, 36 | Supplier configSupplier) { 37 | this.collectorService = collectorService; 38 | this.configSupplier = configSupplier; 39 | } 40 | 41 | @Override 42 | public boolean runsForever() { 43 | return false; 44 | } 45 | 46 | @Override 47 | public boolean stopOnGracefulShutdown() { 48 | return true; 49 | } 50 | 51 | @Override 52 | public boolean masterOnly() { 53 | return true; 54 | } 55 | 56 | @Override 57 | public boolean startOnThisNode() { 58 | return true; 59 | } 60 | 61 | @Override 62 | public boolean isDaemon() { 63 | return true; 64 | } 65 | 66 | @Override 67 | public int getInitialDelaySeconds() { 68 | return 0; 69 | } 70 | 71 | @Override 72 | public int getPeriodSeconds() { 73 | return 60 * 60; 74 | } 75 | 76 | @Override 77 | protected Logger getLogger() { 78 | return LOG; 79 | } 80 | 81 | @Override 82 | public void doRun() { 83 | final int purgedCollectors = collectorService.destroyExpired(configSupplier.get().collectorExpirationThreshold()); 84 | LOG.debug("Purged {} inactive collectors.", purgedCollectors); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/main/java/org/graylog/plugins/collector/permissions/CollectorRestPermissions.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | package org.graylog.plugins.collector.permissions; 18 | 19 | import com.google.common.collect.ImmutableSet; 20 | import org.graylog2.plugin.security.Permission; 21 | import org.graylog2.plugin.security.PluginPermissions; 22 | 23 | import java.util.Collections; 24 | import java.util.Set; 25 | 26 | import static org.graylog2.plugin.security.Permission.create; 27 | 28 | public class CollectorRestPermissions implements PluginPermissions { 29 | public static final String COLLECTORS_READ = "collectors:read"; 30 | public static final String COLLECTORS_CREATE = "collectors:create"; 31 | public static final String COLLECTORS_UPDATE = "collectors:update"; 32 | public static final String COLLECTORS_DELETE = "collectors:delete"; 33 | 34 | private final ImmutableSet permissions = ImmutableSet.of( 35 | create(COLLECTORS_READ, "Read collectors"), 36 | create(COLLECTORS_CREATE, "Create collectors"), 37 | create(COLLECTORS_UPDATE, "Update collectors"), 38 | create(COLLECTORS_DELETE, "Delete collectors") 39 | ); 40 | 41 | @Override 42 | public Set permissions() { 43 | return permissions; 44 | } 45 | 46 | @Override 47 | public Set readerBasePermissions() { 48 | return Collections.emptySet(); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/org/graylog/plugins/collector/system/CollectorSystemConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | package org.graylog.plugins.collector.system; 18 | 19 | import com.fasterxml.jackson.annotation.JsonAutoDetect; 20 | import com.fasterxml.jackson.annotation.JsonCreator; 21 | import com.fasterxml.jackson.annotation.JsonProperty; 22 | import com.google.auto.value.AutoValue; 23 | import org.joda.time.Period; 24 | 25 | import javax.annotation.Nullable; 26 | 27 | import static com.google.common.base.MoreObjects.firstNonNull; 28 | 29 | @JsonAutoDetect 30 | @AutoValue 31 | public abstract class CollectorSystemConfiguration { 32 | 33 | private static final Period DEFAULT_EXPIRATION_PERIOD = Period.days(14); 34 | private static final Period DEFAULT_INACTIVE_THRESHOLD = Period.minutes(1); 35 | private static final Period DEFAULT_UPDATE_INTERVAL = Period.seconds(30); 36 | private static final boolean DEFAULT_SEND_STATUS = true; 37 | private static final boolean DEFAULT_CONFIG_OVERRIDE = false; 38 | 39 | @JsonProperty("collector_expiration_threshold") 40 | public abstract Period collectorExpirationThreshold(); 41 | 42 | @JsonProperty("collector_inactive_threshold") 43 | public abstract Period collectorInactiveThreshold(); 44 | 45 | @JsonProperty("collector_update_interval") 46 | public abstract Period collectorUpdateInterval(); 47 | 48 | @JsonProperty("collector_send_status") 49 | public abstract boolean collectorSendStatus(); 50 | 51 | @JsonProperty("collector_configuration_override") 52 | public abstract boolean collectorConfigurationOverride(); 53 | 54 | @JsonCreator 55 | public static CollectorSystemConfiguration create(@JsonProperty("collector_expiration_threshold") Period expirationThreshold, 56 | @JsonProperty("collector_inactive_threshold") Period inactiveThreshold, 57 | @JsonProperty("collector_update_interval") @Nullable Period updateInterval, 58 | @JsonProperty("collector_send_status") @Nullable Boolean sendStatus, 59 | @JsonProperty("collector_configuration_override") @Nullable Boolean configurationOverride) { 60 | return builder() 61 | .collectorExpirationThreshold(expirationThreshold) 62 | .collectorInactiveThreshold(inactiveThreshold) 63 | .collectorUpdateInterval(firstNonNull(updateInterval, DEFAULT_UPDATE_INTERVAL)) 64 | .collectorSendStatus(firstNonNull(sendStatus, DEFAULT_SEND_STATUS)) 65 | .collectorConfigurationOverride(firstNonNull(configurationOverride, DEFAULT_CONFIG_OVERRIDE)) 66 | .build(); 67 | } 68 | 69 | public static CollectorSystemConfiguration defaultConfiguration() { 70 | return builder() 71 | .collectorExpirationThreshold(DEFAULT_EXPIRATION_PERIOD) 72 | .collectorInactiveThreshold(DEFAULT_INACTIVE_THRESHOLD) 73 | .collectorUpdateInterval(DEFAULT_UPDATE_INTERVAL) 74 | .collectorSendStatus(DEFAULT_SEND_STATUS) 75 | .collectorConfigurationOverride(DEFAULT_CONFIG_OVERRIDE) 76 | .build(); 77 | } 78 | 79 | public static Builder builder() { 80 | return new AutoValue_CollectorSystemConfiguration.Builder(); 81 | } 82 | 83 | public abstract Builder toBuilder(); 84 | 85 | @AutoValue.Builder 86 | public static abstract class Builder { 87 | public abstract Builder collectorExpirationThreshold(Period expirationThreshold); 88 | 89 | public abstract Builder collectorInactiveThreshold(Period inactiveThreshold); 90 | 91 | public abstract Builder collectorUpdateInterval(Period updateInterval); 92 | 93 | public abstract Builder collectorSendStatus(boolean sendStatus); 94 | 95 | public abstract Builder collectorConfigurationOverride(boolean configurationOverride); 96 | 97 | public abstract CollectorSystemConfiguration build(); 98 | } 99 | } -------------------------------------------------------------------------------- /src/main/java/org/graylog/plugins/collector/system/CollectorSystemConfigurationSupplier.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | package org.graylog.plugins.collector.system; 18 | 19 | import com.google.common.base.Supplier; 20 | import org.graylog2.plugin.cluster.ClusterConfigService; 21 | 22 | import javax.annotation.Nonnull; 23 | import javax.inject.Inject; 24 | 25 | public class CollectorSystemConfigurationSupplier implements Supplier { 26 | private final ClusterConfigService clusterConfigService; 27 | private final CollectorSystemConfiguration config; 28 | 29 | @Inject 30 | public CollectorSystemConfigurationSupplier(ClusterConfigService clusterConfigService) { 31 | this.clusterConfigService = clusterConfigService; 32 | this.config = null; 33 | } 34 | 35 | public CollectorSystemConfigurationSupplier(@Nonnull CollectorSystemConfiguration config) { 36 | this.clusterConfigService = null; 37 | this.config = config; 38 | } 39 | 40 | @Override 41 | public CollectorSystemConfiguration get() { 42 | if (config != null) { 43 | return config; 44 | } else if (clusterConfigService != null) { 45 | return clusterConfigService.getOrDefault(CollectorSystemConfiguration.class, 46 | CollectorSystemConfiguration.defaultConfiguration()); 47 | } else { 48 | throw new IllegalStateException("Neither config nor clusterConfigService are set. This should not happen!"); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/services/org.graylog2.plugin.Plugin: -------------------------------------------------------------------------------- 1 | org.graylog.plugins.collector.CollectorPlugin 2 | -------------------------------------------------------------------------------- /src/main/resources/org.graylog.plugins.graylog-plugin-collector/graylog-plugin.properties: -------------------------------------------------------------------------------- 1 | # The plugin version 2 | version=${project.version} 3 | 4 | # The required Graylog server version 5 | graylog.version=${graylog.version} 6 | 7 | # When set to true (the default) the plugin gets a separate class loader 8 | # when loading the plugin. When set to false, the plugin shares a class loader 9 | # with other plugins that have isolated=false. 10 | # 11 | # Do not disable this unless this plugin depends on another plugin! 12 | isolated=true 13 | -------------------------------------------------------------------------------- /src/main/resources/snippets/defaults/nxlog.tmpl: -------------------------------------------------------------------------------- 1 | {{if .Linux}} 2 | User nxlog 3 | Group nxlog 4 | {{if eq .LinuxPlatform "debian"}} 5 | Moduledir /usr/lib/nxlog/modules 6 | CacheDir /var/spool/collector-sidecar/nxlog 7 | PidFile /var/run/graylog/collector-sidecar/nxlog.pid 8 | {{end}} 9 | {{if eq .LinuxPlatform "redhat"}} 10 | Moduledir /usr/libexec/nxlog/modules 11 | CacheDir /var/spool/collector-sidecar/nxlog 12 | PidFile /var/run/graylog/collector-sidecar/nxlog.pid 13 | {{end}} 14 | define LOGFILE /var/log/graylog/collector-sidecar/nxlog.log 15 | LogFile %LOGFILE% 16 | LogLevel INFO 17 | 18 | 19 | Module xm_fileop 20 | 21 | When @daily 22 | Exec file_cycle('%LOGFILE%', 7); 23 | 24 | 25 | {{end}} 26 | {{if .Windows}} 27 | Moduledir %ROOT%\modules 28 | CacheDir %ROOT%\data 29 | Pidfile %ROOT%\data\nxlog.pid 30 | SpoolDir %ROOT%\data 31 | LogFile %ROOT%\data\nxlog.log 32 | LogLevel INFO 33 | 34 | 35 | Module xm_fileop 36 | 37 | When @daily 38 | Exec file_cycle('%ROOT%\data\nxlog.log', 7); 39 | 40 | 41 | {{end}} -------------------------------------------------------------------------------- /src/test/java/org/graylog/plugins/collector/collectors/CollectorServiceImplTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | package org.graylog.plugins.collector.collectors; 18 | 19 | import com.mongodb.client.MongoCollection; 20 | import org.bson.Document; 21 | import org.graylog.testing.mongodb.MongoDBFixtures; 22 | import org.graylog.testing.mongodb.MongoDBInstance; 23 | import org.graylog2.bindings.providers.MongoJackObjectMapperProvider; 24 | import org.graylog2.database.DbEntity; 25 | import org.graylog2.shared.bindings.ObjectMapperModule; 26 | import org.graylog2.shared.bindings.ValidatorModule; 27 | import org.joda.time.DateTime; 28 | import org.joda.time.DateTimeZone; 29 | import org.jukito.JukitoRunner; 30 | import org.jukito.UseModules; 31 | import org.junit.Before; 32 | import org.junit.Rule; 33 | import org.junit.Test; 34 | import org.junit.runner.RunWith; 35 | 36 | import javax.validation.Validator; 37 | import java.util.List; 38 | 39 | import static org.junit.Assert.assertEquals; 40 | import static org.junit.Assert.assertNotNull; 41 | import static org.junit.Assert.assertNull; 42 | import static org.mockito.Mockito.mock; 43 | import static org.mockito.Mockito.when; 44 | 45 | @RunWith(JukitoRunner.class) 46 | @UseModules({ObjectMapperModule.class, ValidatorModule.class, CollectorTestPasswordSecretModule.class}) 47 | public class CollectorServiceImplTest { 48 | @Rule 49 | public final MongoDBInstance mongodb = MongoDBInstance.createForClass(); 50 | 51 | private CollectorService collectorService; 52 | 53 | @Before 54 | public void setUp(MongoJackObjectMapperProvider mapperProvider, 55 | Validator validator) throws Exception { 56 | this.collectorService = new CollectorServiceImpl(mongodb.mongoConnection(), mapperProvider, validator); 57 | } 58 | 59 | @Test 60 | public void testCountEmptyCollection() throws Exception { 61 | final long result = this.collectorService.count(); 62 | 63 | assertEquals(0, result); 64 | } 65 | 66 | @Test 67 | @MongoDBFixtures("collectorsMultipleDocuments.json") 68 | public void testCountNonEmptyCollection() throws Exception { 69 | final long result = this.collectorService.count(); 70 | 71 | assertEquals(3, result); 72 | } 73 | 74 | @Test 75 | public void testSaveFirstRecord() throws Exception { 76 | final Collector collector = CollectorImpl.create("collectorId", "nodeId", "0.0.1", CollectorNodeDetails.create("DummyOS 1.0", null, null, null, null, null), DateTime.now(DateTimeZone.UTC)); 77 | 78 | final Collector result = this.collectorService.save(collector); 79 | 80 | final String collectionName = CollectorImpl.class.getAnnotation(DbEntity.class).collection(); 81 | MongoCollection collection = mongodb.mongoConnection().getMongoDatabase().getCollection(collectionName); 82 | Document document = collection.find().first(); 83 | Document nodeDetails = document.get("node_details", Document.class); 84 | 85 | assertNotNull(result); 86 | assertEquals("collectorId", document.get("id")); 87 | assertEquals("nodeId", document.get("node_id")); 88 | assertEquals("0.0.1", document.get("collector_version")); 89 | assertEquals("DummyOS 1.0", nodeDetails.get("operating_system")); 90 | } 91 | 92 | @Test 93 | @MongoDBFixtures("collectorsMultipleDocuments.json") 94 | public void testAll() throws Exception { 95 | final List collectors = this.collectorService.all(); 96 | 97 | assertNotNull(collectors); 98 | assertEquals(3, collectors.size()); 99 | } 100 | 101 | @Test 102 | public void testAllEmptyCollection() throws Exception { 103 | final List collectors = this.collectorService.all(); 104 | 105 | assertNotNull(collectors); 106 | assertEquals(0, collectors.size()); 107 | } 108 | 109 | @Test 110 | @MongoDBFixtures("collectorsMultipleDocuments.json") 111 | public void testFindById() throws Exception { 112 | final String collector1id = "collector1id"; 113 | 114 | final Collector collector = this.collectorService.findById(collector1id); 115 | 116 | assertNotNull(collector); 117 | assertEquals(collector1id, collector.getId()); 118 | } 119 | 120 | @Test 121 | @MongoDBFixtures("collectorsMultipleDocuments.json") 122 | public void testFindByIdNonexisting() throws Exception { 123 | final String collector1id = "nonexisting"; 124 | 125 | final Collector collector = this.collectorService.findById(collector1id); 126 | 127 | assertNull(collector); 128 | } 129 | 130 | @Test 131 | @MongoDBFixtures("collectorsMultipleDocuments.json") 132 | public void testFindByNodeId() throws Exception { 133 | final String nodeId = "uniqueid1"; 134 | 135 | final List collectors = this.collectorService.findByNodeId(nodeId); 136 | 137 | assertNotNull(collectors); 138 | assertEquals(1, collectors.size()); 139 | 140 | for (Collector collector : collectors) { 141 | assertNotNull(collector); 142 | assertEquals(nodeId, collector.getNodeId()); 143 | } 144 | } 145 | 146 | @Test 147 | @MongoDBFixtures("collectorsMultipleDocuments.json") 148 | public void testFindByNodeIdNonexisting() throws Exception { 149 | final String nodeId = "nonexisting"; 150 | 151 | final List collectors = this.collectorService.findByNodeId(nodeId); 152 | 153 | assertNotNull(collectors); 154 | assertEquals(0, collectors.size()); 155 | } 156 | 157 | @Test 158 | @MongoDBFixtures("collectorsMultipleDocuments.json") 159 | public void testDestroy() throws Exception { 160 | final Collector collector = mock(Collector.class); 161 | when(collector.getId()).thenReturn("collector2id"); 162 | 163 | final int result = this.collectorService.destroy(collector); 164 | 165 | final String collectionName = CollectorImpl.class.getAnnotation(DbEntity.class).collection(); 166 | assertEquals(1, result); 167 | assertEquals(2, mongodb.mongoConnection().getMongoDatabase().getCollection(collectionName).countDocuments()); 168 | } 169 | } -------------------------------------------------------------------------------- /src/test/java/org/graylog/plugins/collector/collectors/CollectorTestPasswordSecretModule.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | package org.graylog.plugins.collector.collectors; 18 | 19 | import com.google.inject.name.Names; 20 | import org.graylog2.plugin.inject.Graylog2Module; 21 | 22 | public class CollectorTestPasswordSecretModule extends Graylog2Module { 23 | public static final String TEST_PASSWORD_SECRET = "f9a79178-c949-446d-b0ae-c6d5d9a40ba8"; 24 | 25 | @Override 26 | protected void configure() { 27 | bind(String.class).annotatedWith(Names.named("password_secret")).toInstance(TEST_PASSWORD_SECRET); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/test/java/org/graylog/plugins/collector/collectors/rest/CollectorResourceTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | package org.graylog.plugins.collector.collectors.rest; 18 | 19 | import com.google.common.collect.Lists; 20 | import org.graylog.plugins.collector.collectors.Collector; 21 | import org.graylog.plugins.collector.collectors.rest.models.CollectorNodeDetailsSummary; 22 | import org.graylog.plugins.collector.collectors.rest.models.requests.CollectorRegistrationRequest; 23 | import org.graylog.plugins.collector.collectors.rest.models.responses.CollectorList; 24 | import org.graylog.plugins.collector.collectors.rest.models.responses.CollectorSummary; 25 | import org.graylog.plugins.collector.collectors.rest.resources.RestResourceBaseTest; 26 | import org.graylog.plugins.collector.system.CollectorSystemConfiguration; 27 | import org.graylog.plugins.collector.system.CollectorSystemConfigurationSupplier; 28 | import org.junit.Before; 29 | import org.junit.Ignore; 30 | import org.junit.Test; 31 | import org.junit.runner.RunWith; 32 | import org.mockito.Mock; 33 | import org.mockito.runners.MockitoJUnitRunner; 34 | 35 | import javax.ws.rs.NotFoundException; 36 | import javax.ws.rs.core.Response; 37 | import java.util.List; 38 | 39 | import static org.graylog.plugins.collector.collectors.rest.assertj.ResponseAssert.assertThat; 40 | import static org.junit.Assert.assertEquals; 41 | import static org.junit.Assert.assertNotNull; 42 | import static org.junit.Assert.assertNull; 43 | import static org.mockito.Matchers.any; 44 | import static org.mockito.Mockito.mock; 45 | import static org.mockito.Mockito.when; 46 | 47 | @RunWith(value = MockitoJUnitRunner.class) 48 | public class CollectorResourceTest extends RestResourceBaseTest { 49 | private CollectorResource resource; 50 | private List collectors; 51 | 52 | @Mock 53 | private org.graylog.plugins.collector.collectors.CollectorService collectorService; 54 | 55 | @Before 56 | public void setUp() throws Exception { 57 | this.collectors = getDummyCollectorList(); 58 | this.resource = new CollectorResource(collectorService, new CollectorSystemConfigurationSupplier(CollectorSystemConfiguration.defaultConfiguration())); 59 | when(collectorService.all()).thenReturn(collectors); 60 | } 61 | 62 | @Test 63 | public void testList() throws Exception { 64 | final CollectorList response = this.resource.list(); 65 | 66 | assertNotNull(response); 67 | assertNotNull(response.collectors()); 68 | assertEquals("Collector list should be of same size as dummy list", collectors.size(), response.collectors().size()); 69 | } 70 | 71 | @Test(expected = NotFoundException.class) 72 | public void testGetNotExisting() throws Exception { 73 | final CollectorSummary response = this.resource.get("Nonexisting"); 74 | 75 | assertNull(response); 76 | } 77 | 78 | @Test 79 | public void testGet() throws Exception { 80 | final Collector collector = collectors.get(collectors.size() - 1); 81 | when(collectorService.findById(collector.getId())).thenReturn(collector); 82 | final CollectorSummary collectorSummary = mock(CollectorSummary.class); 83 | when(collector.toSummary(any(CollectorResource.LostCollectorFunction.class))).thenReturn(collectorSummary); 84 | 85 | final CollectorSummary response = this.resource.get(collector.getId()); 86 | 87 | assertNotNull(response); 88 | assertEquals(collectorSummary, response); 89 | } 90 | 91 | private Collector getDummyCollector(String id) { 92 | final Collector collector = mock(Collector.class); 93 | when(collector.getId()).thenReturn(id); 94 | 95 | return collector; 96 | } 97 | 98 | private List getDummyCollectorList() { 99 | final Collector collector1 = getDummyCollector("collector1id"); 100 | final Collector collector2 = getDummyCollector("collector2id"); 101 | final Collector collector3 = getDummyCollector("collector3id"); 102 | 103 | return Lists.newArrayList(collector1, collector2, collector3); 104 | } 105 | 106 | @Test 107 | public void testRegister() throws Exception { 108 | final CollectorRegistrationRequest input = CollectorRegistrationRequest.create("nodeId", CollectorNodeDetailsSummary.create("DummyOS 1.0", null, null, null, null, null)); 109 | 110 | final Response response = this.resource.register("collectorId", input, "0.0.1"); 111 | 112 | assertThat(response).isSuccess(); 113 | } 114 | 115 | @Test 116 | @Ignore 117 | public void testRegisterInvalidCollectorId() throws Exception { 118 | final CollectorRegistrationRequest invalid = CollectorRegistrationRequest.create("nodeId", CollectorNodeDetailsSummary.create("DummyOS 1.0", null, null, null, null, null)); 119 | 120 | final Response response = this.resource.register("", invalid, "0.0.1"); 121 | 122 | assertThat(response).isError(); 123 | assertThat(response).isStatus(Response.Status.BAD_REQUEST); 124 | } 125 | 126 | @Test 127 | @Ignore 128 | public void testRegisterInvalidNodeId() throws Exception { 129 | final CollectorRegistrationRequest invalid = CollectorRegistrationRequest.create("", CollectorNodeDetailsSummary.create("DummyOS 1.0", null, null, null, null, null)); 130 | 131 | final Response response = this.resource.register("collectorId", invalid, "0.0.1"); 132 | 133 | assertThat(response).isError(); 134 | assertThat(response).isStatus(Response.Status.BAD_REQUEST); 135 | } 136 | 137 | @Test 138 | @Ignore 139 | public void testRegisterMissingNodeDetails() throws Exception { 140 | final CollectorRegistrationRequest invalid = CollectorRegistrationRequest.create("nodeId", null); 141 | 142 | final Response response = this.resource.register("collectorId", invalid, "0.0.1"); 143 | 144 | assertThat(response).isError(); 145 | assertThat(response).isStatus(Response.Status.BAD_REQUEST); 146 | } 147 | 148 | @Test 149 | @Ignore 150 | public void testRegisterMissingOperatingSystem() throws Exception { 151 | final CollectorRegistrationRequest invalid = CollectorRegistrationRequest.create("nodeId", CollectorNodeDetailsSummary.create("", null, null, null, null, null)); 152 | 153 | final Response response = this.resource.register("collectorId", invalid, "0.0.1"); 154 | 155 | assertThat(response).isError(); 156 | assertThat(response).isStatus(Response.Status.BAD_REQUEST); 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /src/test/java/org/graylog/plugins/collector/collectors/rest/assertj/ResponseAssert.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | package org.graylog.plugins.collector.collectors.rest.assertj; 18 | 19 | import org.assertj.core.api.AbstractAssert; 20 | 21 | import javax.ws.rs.core.Response; 22 | 23 | public class ResponseAssert extends AbstractAssert { 24 | public ResponseAssert(Response actual) { 25 | super(actual, ResponseAssert.class); 26 | } 27 | 28 | public static ResponseAssert assertThat(Response response) { 29 | return new ResponseAssert(response); 30 | } 31 | 32 | public ResponseAssert isSuccess() { 33 | isNotNull(); 34 | 35 | final Response.Status.Family statusFamily = actual.getStatusInfo().getFamily(); 36 | 37 | if (statusFamily != Response.Status.Family.SUCCESSFUL) { 38 | failWithMessage("Response was expected to be a success, but is <%s>", statusFamily); 39 | } 40 | 41 | return this; 42 | } 43 | 44 | public ResponseAssert isError() { 45 | isNotNull(); 46 | 47 | final Response.Status.Family statusFamily = actual.getStatusInfo().getFamily(); 48 | 49 | if (statusFamily == Response.Status.Family.CLIENT_ERROR || statusFamily == Response.Status.Family.SERVER_ERROR) { 50 | failWithMessage("Response was expected to be an error, but is <%s>", statusFamily); 51 | } 52 | 53 | return this; 54 | } 55 | 56 | public ResponseAssert isStatus(Response.Status expected) { 57 | isNotNull(); 58 | 59 | final Response.StatusType status = actual.getStatusInfo(); 60 | 61 | if (status != expected) 62 | failWithMessage("Response status was expected to be <%s>, but is <%s>", expected, status); 63 | 64 | return this; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/test/java/org/graylog/plugins/collector/collectors/rest/resources/RestResourceBaseTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | package org.graylog.plugins.collector.collectors.rest.resources; 18 | 19 | import org.apache.shiro.subject.Subject; 20 | import org.graylog2.shared.bindings.GuiceInjectorHolder; 21 | import org.graylog2.shared.rest.resources.RestResource; 22 | import org.junit.Before; 23 | import org.junit.Test; 24 | 25 | import java.util.Collections; 26 | 27 | import static org.junit.Assert.assertFalse; 28 | import static org.junit.Assert.assertTrue; 29 | import static org.mockito.ArgumentMatchers.any; 30 | import static org.mockito.Mockito.mock; 31 | import static org.mockito.Mockito.when; 32 | 33 | public class RestResourceBaseTest { 34 | @Before 35 | public void setUpInjector() throws Exception { 36 | // The list of modules is empty for now so only JIT injection will be used. 37 | GuiceInjectorHolder.createInjector(Collections.emptyList()); 38 | } 39 | 40 | 41 | @Test 42 | public void testisAnyPermitted() { 43 | final PermissionDeniedResource failingResource = new PermissionDeniedResource(); 44 | final AllPermissionsGrantedResource allGranted = new AllPermissionsGrantedResource(); 45 | final SomePermissionsGrantedResource someGranted = new SomePermissionsGrantedResource(); 46 | 47 | assertFalse("User doesn't have any permissions", failingResource.runCheck()); 48 | assertTrue("User has all permissions", allGranted.runCheck()); 49 | assertTrue("User has some permissions", someGranted.runCheck()); 50 | } 51 | 52 | private static class PermissionDeniedResource extends RestResource { 53 | @Override 54 | protected Subject getSubject() { 55 | final Subject mock = mock(Subject.class); 56 | when(mock.isPermitted((String[]) any())).thenReturn(new boolean[]{false, false}); 57 | return mock; 58 | } 59 | 60 | public boolean runCheck() { 61 | return isAnyPermitted(new String[]{"a:b", "a:c"}, "instance"); 62 | } 63 | } 64 | 65 | private static class AllPermissionsGrantedResource extends RestResource { 66 | @Override 67 | protected Subject getSubject() { 68 | final Subject mock = mock(Subject.class); 69 | when(mock.isPermitted((String[]) any())).thenReturn(new boolean[]{true, true}); 70 | return mock; 71 | } 72 | 73 | public boolean runCheck() { 74 | return isAnyPermitted(new String[]{"a:b", "a:c"}, "instance"); 75 | } 76 | } 77 | 78 | private static class SomePermissionsGrantedResource extends RestResource { 79 | @Override 80 | protected Subject getSubject() { 81 | final Subject mock = mock(Subject.class); 82 | when(mock.isPermitted((String[]) any())).thenReturn(new boolean[]{false, true}); 83 | return mock; 84 | } 85 | 86 | public boolean runCheck() { 87 | return isAnyPermitted(new String[]{"a:b", "a:c"}, "instance"); 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/test/resources/org/graylog/plugins/collector/collectors/CollectorServiceImplTest#testDestroy-expected.json: -------------------------------------------------------------------------------- 1 | { 2 | "collectors": [ 3 | { 4 | "id": "collector1id", 5 | "node_id": "uniqueid1", 6 | "collector_version": "0.0.1", 7 | "node_details": { 8 | "operating_system": "DummyOS 1.0" 9 | }, 10 | "last_seen": "2015-04-01T11:50:20.195Z" 11 | }, 12 | { 13 | "id": "collector3id", 14 | "node_id": "uniqueid3", 15 | "collector_version": "0.0.1", 16 | "node_details": { 17 | "operating_system": "DummyOS 1.0" 18 | }, 19 | "last_seen": "2015-04-01T11:50:20.195Z" 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /src/test/resources/org/graylog/plugins/collector/collectors/collectorsMultipleDocuments.json: -------------------------------------------------------------------------------- 1 | { 2 | "collectors": [ 3 | { 4 | "id": "collector1id", 5 | "node_id": "uniqueid1", 6 | "collector_version": "0.0.1", 7 | "node_details": { 8 | "operating_system": "DummyOS 1.0" 9 | }, 10 | "last_seen": "2015-04-01T11:50:20.195Z" 11 | }, 12 | { 13 | "id": "collector2id", 14 | "node_id": "uniqueid2", 15 | "collector_version": "0.0.1", 16 | "node_details": { 17 | "operating_system": "DummyOS 1.0" 18 | }, 19 | "last_seen": "2015-04-01T11:50:20.195Z" 20 | }, 21 | { 22 | "id": "collector3id", 23 | "node_id": "uniqueid3", 24 | "collector_version": "0.0.1", 25 | "node_details": { 26 | "operating_system": "DummyOS 1.0" 27 | }, 28 | "last_seen": "2015-04-01T11:50:20.195Z" 29 | } 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /src/test/resources/org/graylog/plugins/collector/collectors/collectorsSingleDataset.json: -------------------------------------------------------------------------------- 1 | { 2 | "collectors": [ 3 | { 4 | "id": "collectorId", 5 | "node_id": "nodeId", 6 | "collector_version": "0.0.1", 7 | "node_details": { 8 | "operating_system": "DummyOS 1.0" 9 | }, 10 | "last_seen": "" 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /src/web/collector-configuration/CollapsibleVerbatim.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | import PropTypes from 'prop-types'; 18 | import React from 'react'; 19 | 20 | import { Alert, Collapse } from 'components/bootstrap'; 21 | import { Input } from 'components/bootstrap'; 22 | 23 | class CollapsibleVerbatim extends React.Component { 24 | static propTypes = { 25 | type: PropTypes.string, 26 | value: PropTypes.string, 27 | onChange: PropTypes.func.isRequired, 28 | }; 29 | 30 | constructor(props) { 31 | super(props); 32 | let expanded = false; 33 | if (props.value) { 34 | expanded = true; 35 | } 36 | 37 | this.state = { 38 | expanded: expanded, 39 | }; 40 | } 41 | 42 | _onHandleToggle = (e) => { 43 | e.preventDefault(); 44 | this.setState({ expanded: !this.state.expanded }); 45 | }; 46 | 47 | _getId = (prefixIdName) => { 48 | return prefixIdName + this.props.type; 49 | }; 50 | 51 | render() { 52 | const text = this.state.expanded ? 'Hide' : 'Add'; 53 | 54 | return ( 55 | 56 | {text} verbatim configuration 57 | 58 | 59 | 64 | 65 | 66 | 67 | ); 68 | } 69 | } 70 | 71 | export default CollapsibleVerbatim; 72 | -------------------------------------------------------------------------------- /src/web/collector-configuration/CollectorConfigurationPage.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | import DocsHelper from 'util/DocsHelper'; 18 | 19 | import React from 'react'; 20 | import PropTypes from 'prop-types'; 21 | import createReactClass from 'create-react-class'; 22 | import { DocumentTitle, PageHeader, Spinner } from 'components/common'; 23 | import DocumentationLink from 'components/support/DocumentationLink'; 24 | import withParams from 'routing/withParams'; 25 | import CollectorConfigurationsActions from 'configurations/CollectorConfigurationsActions'; 26 | import style from 'styles/CollectorStyles.lazy.css'; 27 | 28 | import CollectorConfiguration from './CollectorConfiguration'; 29 | import CollectorsPageNavigation from '../collectors/CollectorsPageNavigation'; 30 | 31 | const CollectorConfigurationPage = createReactClass({ 32 | displayName: 'CollectorConfigurationPage', 33 | 34 | propTypes: { 35 | params: PropTypes.object.isRequired, 36 | }, 37 | 38 | getInitialState() { 39 | return { 40 | configuration: undefined, 41 | tags: undefined, 42 | }; 43 | }, 44 | 45 | componentDidMount() { 46 | style.use(); 47 | this._reloadConfiguration(); 48 | this._loadTags(); 49 | }, 50 | 51 | componentWillUnmount() { 52 | style.unuse(); 53 | }, 54 | 55 | _reloadConfiguration() { 56 | CollectorConfigurationsActions.getConfiguration.triggerPromise(this.props.params.id).then(this._setConfiguration); 57 | }, 58 | 59 | _setConfiguration(configuration) { 60 | this.setState({ configuration }); 61 | }, 62 | 63 | _loadTags() { 64 | CollectorConfigurationsActions.listTags.triggerPromise() 65 | .then((tags) => { 66 | this.setState({ tags }); 67 | }); 68 | }, 69 | 70 | _isLoading() { 71 | return !(this.state.configuration && this.state.tags); 72 | }, 73 | 74 | render() { 75 | if (this._isLoading()) { 76 | return ; 77 | } 78 | 79 | const lifecycleMessage = ( 80 | The Graylog Collector plugin is discontinued and has been superseded by the new Sidecars. 81 | ); 82 | 83 | return ( 84 | 85 | 86 | Collector {this.state.configuration.name} Configuration} 87 | lifecycle="legacy" 88 | lifecycleMessage={lifecycleMessage} 89 | documentationLink={{ 90 | title: 'Sidecar documentation', 91 | path: DocsHelper.PAGES.COLLECTOR_SIDECAR, 92 | }}> 93 | 94 | Use this page to review and manage the configuration for this collector. 95 | 96 | 97 | 100 | 101 | ); 102 | }, 103 | }); 104 | 105 | export default withParams(CollectorConfigurationPage); 106 | -------------------------------------------------------------------------------- /src/web/collector-configuration/CopyInputModal.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | import PropTypes from 'prop-types'; 18 | import React from 'react'; 19 | 20 | import { Button } from 'components/bootstrap'; 21 | import { BootstrapModalForm, Input } from 'components/bootstrap'; 22 | 23 | class CopyInputModal extends React.Component { 24 | static propTypes = { 25 | id: PropTypes.string, 26 | copyInput: PropTypes.func.isRequired, 27 | validInputName: PropTypes.func.isRequired, 28 | }; 29 | 30 | static defaultProps = { 31 | id: '', 32 | name: '', 33 | }; 34 | 35 | state = { 36 | id: this.props.id, 37 | name: '', 38 | error: false, 39 | error_message: '', 40 | showModal: false, 41 | }; 42 | 43 | openModal = () => { 44 | this.setState({ showModal: true }); 45 | }; 46 | 47 | _getId = (prefixIdName) => { 48 | return prefixIdName + this.state.name; 49 | }; 50 | 51 | _closeModal = () => { 52 | this.setState({ showModal: false }); 53 | }; 54 | 55 | _saved = () => { 56 | this._closeModal(); 57 | this.setState({ name: '' }); 58 | }; 59 | 60 | _save = () => { 61 | const configuration = this.state; 62 | 63 | if (!configuration.error) { 64 | this.props.copyInput(this.props.id, this.state.name, this._saved); 65 | } 66 | }; 67 | 68 | _changeName = (event) => { 69 | this.setState({ name: event.target.value }); 70 | }; 71 | 72 | render() { 73 | return ( 74 | 75 | 80 | 85 |
86 | 95 |
96 |
97 |
98 | ); 99 | } 100 | } 101 | 102 | export default CopyInputModal; 103 | -------------------------------------------------------------------------------- /src/web/collector-configuration/CopyOutputModal.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | import PropTypes from 'prop-types'; 18 | import React from 'react'; 19 | 20 | import { Button } from 'components/bootstrap'; 21 | import { BootstrapModalForm, Input } from 'components/bootstrap'; 22 | 23 | class CopyOutputModal extends React.Component { 24 | static propTypes = { 25 | id: PropTypes.string, 26 | copyOutput: PropTypes.func.isRequired, 27 | validOutputName: PropTypes.func.isRequired, 28 | }; 29 | 30 | static defaultProps = { 31 | id: '', 32 | name: '', 33 | }; 34 | 35 | state = { 36 | id: this.props.id, 37 | name: '', 38 | error: false, 39 | error_message: '', 40 | showModal: false, 41 | }; 42 | 43 | openModal = () => { 44 | this.setState({ showModal: true }); 45 | }; 46 | 47 | _getId = (prefixIdName) => { 48 | return prefixIdName + this.state.name; 49 | }; 50 | 51 | _closeModal = () => { 52 | this.setState({ showModal: false }); 53 | }; 54 | 55 | _saved = () => { 56 | this._closeModal(); 57 | this.setState({ name: '' }); 58 | }; 59 | 60 | _save = () => { 61 | const configuration = this.state; 62 | 63 | if (!configuration.error) { 64 | this.props.copyOutput(this.props.id, this.state.name, this._saved); 65 | } 66 | }; 67 | 68 | _changeName = (event) => { 69 | this.setState({ name: event.target.value }); 70 | }; 71 | 72 | render() { 73 | return ( 74 | 75 | 80 | 85 |
86 | 95 |
96 |
97 |
98 | ); 99 | } 100 | } 101 | 102 | export default CopyOutputModal; 103 | -------------------------------------------------------------------------------- /src/web/collector-configuration/CopySnippetModal.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | import PropTypes from 'prop-types'; 18 | import React from 'react'; 19 | 20 | import { Button } from 'components/bootstrap'; 21 | import { BootstrapModalForm, Input } from 'components/bootstrap'; 22 | 23 | class CopySnippetModal extends React.Component { 24 | static propTypes = { 25 | id: PropTypes.string, 26 | copySnippet: PropTypes.func.isRequired, 27 | validSnippetName: PropTypes.func.isRequired, 28 | }; 29 | 30 | static defaultProps = { 31 | id: '', 32 | name: '', 33 | }; 34 | 35 | state = { 36 | id: this.props.id, 37 | name: '', 38 | error: false, 39 | error_message: '', 40 | showModal: false, 41 | }; 42 | 43 | openModal = () => { 44 | this.setState({ showModal: true }); 45 | }; 46 | 47 | _getId = (prefixIdName) => { 48 | return prefixIdName + this.state.name; 49 | }; 50 | 51 | _closeModal = () => { 52 | this.setState({ showModal: false }); 53 | }; 54 | 55 | _saved = () => { 56 | this._closeModal(); 57 | this.setState({ name: '' }); 58 | }; 59 | 60 | _save = () => { 61 | const configuration = this.state; 62 | 63 | if (!configuration.error) { 64 | this.props.copySnippet(this.props.id, this.state.name, this._saved); 65 | } 66 | }; 67 | 68 | _changeName = (event) => { 69 | this.setState({ name: event.target.value }); 70 | }; 71 | 72 | render() { 73 | return ( 74 | 75 | 80 | 85 |
86 | 95 |
96 |
97 |
98 | ); 99 | } 100 | } 101 | 102 | export default CopySnippetModal; 103 | -------------------------------------------------------------------------------- /src/web/collector-configuration/DeleteConfirmButton.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | import PropTypes from 'prop-types'; 18 | import React from 'react'; 19 | 20 | import { Button } from 'components/bootstrap'; 21 | 22 | class DeleteConfirmButton extends React.Component { 23 | static propTypes = { 24 | entity: PropTypes.object.isRequired, 25 | type: PropTypes.string.isRequired, 26 | onClick: PropTypes.func.isRequired, 27 | }; 28 | 29 | handleClick = () => { 30 | if (window.confirm(`You are about to delete ${this.props.type} "${this.props.entity.name}". Are you sure?`)) { 31 | this.props.onClick(this.props.entity); 32 | } 33 | }; 34 | 35 | render() { 36 | return ( 37 | 40 | ); 41 | } 42 | } 43 | 44 | export default DeleteConfirmButton; 45 | -------------------------------------------------------------------------------- /src/web/collector-configuration/EditOutputModal.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | import PropTypes from 'prop-types'; 18 | import React from 'react'; 19 | 20 | import { Button } from 'components/bootstrap'; 21 | import { BootstrapModalForm, Input } from 'components/bootstrap'; 22 | import { Select } from 'components/common'; 23 | 24 | import EditOutputFields from './EditOutputFields'; 25 | 26 | class EditOutputModal extends React.Component { 27 | static propTypes = { 28 | id: PropTypes.string, 29 | name: PropTypes.string, 30 | backend: PropTypes.string, 31 | type: PropTypes.string, 32 | properties: PropTypes.object, 33 | create: PropTypes.bool, 34 | saveOutput: PropTypes.func.isRequired, 35 | validOutputName: PropTypes.func.isRequired, 36 | selectedGroup: PropTypes.string.isRequired, 37 | outputList: PropTypes.array.isRequired, 38 | }; 39 | 40 | static defaultProps = { 41 | id: '', 42 | name: '', 43 | properties: {}, 44 | }; 45 | 46 | state = { 47 | id: this.props.id, 48 | name: this.props.name, 49 | backend: this.props.backend, 50 | type: this.props.type, 51 | properties: this.props.properties, 52 | selectedType: (this.props.backend && this.props.type) ? `${this.props.backend}:${this.props.type}` : undefined, 53 | error: false, 54 | errorMessage: '', 55 | errorFields: [], 56 | showModal: false, 57 | }; 58 | 59 | openModal = () => { 60 | this.setState({ showModal: true }); 61 | }; 62 | 63 | _getId = (prefixIdName) => { 64 | return prefixIdName + this.state.name; 65 | }; 66 | 67 | _closeModal = () => { 68 | this.setState({ showModal: false }); 69 | }; 70 | 71 | _saved = () => { 72 | this._closeModal(); 73 | if (this.props.create) { 74 | this.setState({ name: '', backend: '', type: '', selectedType: '', properties: {} }); 75 | } 76 | }; 77 | 78 | _save = () => { 79 | const configuration = this.state; 80 | 81 | if (!configuration.error) { 82 | this.props.saveOutput(configuration, this._saved); 83 | } 84 | }; 85 | 86 | _changeErrorState = (error, message, id) => { 87 | const errorFields = this.state.errorFields.slice(); 88 | const index = errorFields.indexOf(id); 89 | if (error && index == -1) { 90 | errorFields.push(id); 91 | } 92 | if (!error && index > -1) { 93 | errorFields.splice(index, 1); 94 | } 95 | this.setState({ error: error, errorMessage: message, errorFields: errorFields }); 96 | }; 97 | 98 | _changeName = (event) => { 99 | this.setState({ name: event.target.value }); 100 | }; 101 | 102 | _changeProperties = (properties) => { 103 | this.setState({ properties }); 104 | }; 105 | 106 | _changeType = (type) => { 107 | const backendAndType = type.split(/:/, 2); 108 | this.setState({ selectedType: type, backend: backendAndType[0], type: backendAndType[1], properties: {} }); 109 | }; 110 | 111 | _injectProperties = (key, value) => { 112 | const { properties } = this.state; 113 | if (properties) { 114 | properties[key] = value; 115 | } 116 | this.setState({ properties }); 117 | }; 118 | 119 | _fieldError = (name) => { 120 | return this.state.error && this.state.errorFields.indexOf(this._getId(name)) !== -1; 121 | }; 122 | 123 | render() { 124 | let triggerButtonContent; 125 | if (this.props.create) { 126 | triggerButtonContent = 'Create Output'; 127 | } else { 128 | triggerButtonContent = Edit; 129 | } 130 | 131 | return ( 132 | 133 | 138 | 144 |
145 | 154 | 155 | 126 | 129 | 144 |
145 |
146 |
147 | ); 148 | } 149 | } 150 | 151 | export default EditSnippetModal; 152 | -------------------------------------------------------------------------------- /src/web/collector-configuration/TagsSelect.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | import PropTypes from 'prop-types'; 18 | import React from 'react'; 19 | 20 | import MultiSelect from 'components/common/MultiSelect'; 21 | 22 | class TagsSelect extends React.Component { 23 | static propTypes = { 24 | tags: PropTypes.arrayOf(PropTypes.string), 25 | availableTags: PropTypes.array.isRequired, 26 | }; 27 | 28 | static defaultProps = { 29 | tags: [], 30 | }; 31 | 32 | getValue = () => { 33 | return this.refs.select.getValue().split(','); 34 | }; 35 | 36 | render() { 37 | const tagsValue = this.props.tags.join(','); 38 | const tagsOptions = this.props.availableTags.map((tag) => { 39 | return { value: tag.name, label: tag.name }; 40 | }); 41 | return ( 42 | 47 | ); 48 | } 49 | } 50 | 51 | export default TagsSelect; 52 | -------------------------------------------------------------------------------- /src/web/collectors/CollectorRow.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | import PropTypes from 'prop-types'; 18 | import React from 'react'; 19 | import createReactClass from 'create-react-class'; 20 | import { LinkContainer } from 'components/common/router'; 21 | 22 | import { Button, Label } from 'components/bootstrap'; 23 | import Routes from 'routing/Routes'; 24 | import { Timestamp } from 'components/common'; 25 | import style from 'styles/CollectorStyles.lazy.css'; 26 | 27 | const CollectorRow = createReactClass({ 28 | displayName: 'CollectorRow', 29 | 30 | propTypes: { 31 | collector: PropTypes.object.isRequired, 32 | }, 33 | 34 | getInitialState() { 35 | return { 36 | showRelativeTime: true, 37 | }; 38 | }, 39 | 40 | componentDidMount() { 41 | style.use(); 42 | }, 43 | 44 | componentWillUnmount() { 45 | style.unuse(); 46 | }, 47 | 48 | _getId(prefixIdName) { 49 | return prefixIdName + this.props.collector.id; 50 | }, 51 | 52 | _getOsGlyph(operatingSystem) { 53 | let glyphClass = 'fa-question-circle'; 54 | const os = operatingSystem.trim().toLowerCase(); 55 | if (os.indexOf('darwin') !== -1 || os.indexOf('mac os') !== -1) { 56 | glyphClass = 'fa-apple'; 57 | } else if (os.indexOf('linux') !== -1) { 58 | glyphClass = 'fa-linux'; 59 | } else if (os.indexOf('win') !== -1) { 60 | glyphClass = 'fa-windows'; 61 | } 62 | 63 | glyphClass += ' collector-os'; 64 | 65 | return (); 66 | }, 67 | 68 | _labelClassForState(state) { 69 | switch (state) { 70 | case 0: 71 | return 'success'; 72 | case 1: 73 | return 'warning'; 74 | case 2: 75 | return 'danger'; 76 | default: 77 | return 'warning'; 78 | } 79 | }, 80 | 81 | _textForState(state) { 82 | switch (state) { 83 | case 0: 84 | return 'Running'; 85 | case 1: 86 | return 'Unknown'; 87 | case 2: 88 | return 'Failing'; 89 | default: 90 | return 'Unknown'; 91 | } 92 | }, 93 | 94 | _tagsAsBadges(collector) { 95 | if (collector.node_details.tags) { 96 | return collector.node_details.tags.map(tag => {tag}); 97 | } 98 | }, 99 | 100 | render() { 101 | const { collector } = this.props; 102 | const collectorClass = collector.active ? '' : 'greyed-out inactive'; 103 | const style = {}; 104 | const annotation = collector.active ? '' : ' (inactive)'; 105 | const osGlyph = this._getOsGlyph(collector.node_details.operating_system); 106 | let collectorState = null; 107 | if (collector.node_details.status) { 108 | collectorState = collector.node_details.status.status; 109 | } 110 | return ( 111 | 112 | 113 | 114 | {collector.node_id} 115 | 116 |

117 | {this._tagsAsBadges(collector)} 118 |

119 | 120 | 121 | 124 | 125 | 126 | {osGlyph} 127 | {collector.node_details.operating_system} 128 | 129 | 130 | 131 | 132 | 133 | {collector.id} 134 | {annotation} 135 | 136 | 137 | {collector.collector_version} 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | ); 146 | }, 147 | }); 148 | 149 | export default CollectorRow; 150 | -------------------------------------------------------------------------------- /src/web/collectors/CollectorsActions.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | import Reflux from 'reflux'; 18 | 19 | const CollectorsActions = Reflux.createActions({ 20 | list: { asyncResult: true }, 21 | getCollector: { asyncResult: true }, 22 | getCollectorActions: { asyncResult: true }, 23 | restartCollectorBackend: { asyncResult: true }, 24 | importCollectorConfiguration: { asyncResult: true }, 25 | }); 26 | 27 | export default CollectorsActions; 28 | -------------------------------------------------------------------------------- /src/web/collectors/CollectorsImportButton.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | import PropTypes from 'prop-types'; 18 | import React from 'react'; 19 | import createReactClass from 'create-react-class'; 20 | 21 | import { Button } from 'components/bootstrap'; 22 | import CollectorsActions from 'collectors/CollectorsActions'; 23 | 24 | const CollectorsImportButton = createReactClass({ 25 | propTypes: { 26 | collector: PropTypes.object.isRequired, 27 | backend: PropTypes.string.isRequired, 28 | onFinish: PropTypes.func, 29 | }, 30 | 31 | getDefaultProps() { 32 | return { 33 | onFinish: () => null, 34 | }; 35 | }, 36 | 37 | getInitialState() { 38 | return { 39 | disabled: false, 40 | text: this.BUTTON_DEFAULT_TEXT, 41 | }; 42 | }, 43 | 44 | componentDidMount() { 45 | this.interval = setInterval(this._refreshButtonState, this.BUTTON_REFRESH); 46 | }, 47 | 48 | componentWillUnmount() { 49 | if (this.interval) { 50 | clearInterval(this.interval); 51 | } 52 | }, 53 | 54 | BUTTON_DEFAULT_TEXT: 'Import Configuration', 55 | BUTTON_REFRESH: 2 * 1000, 56 | 57 | _handleImport() { 58 | CollectorsActions.importCollectorConfiguration(this.props.collector.id, this.props.backend).then(this._disableButton); 59 | }, 60 | 61 | _disableButton() { 62 | this.setState({ disabled: true, text: 'Importing...' }); 63 | }, 64 | 65 | _resetButton(actions) { 66 | let reset = true; 67 | if (actions) { 68 | actions.forEach((action) => { 69 | if (action.backend === this.props.backend && action.properties.import === true) { 70 | reset = false; 71 | } 72 | }); 73 | } 74 | if (reset) { 75 | this.setState({ disabled: false, text: this.BUTTON_DEFAULT_TEXT }); 76 | this.props.onFinish(); 77 | } 78 | }, 79 | 80 | _refreshButtonState() { 81 | if (this.state.disabled) { 82 | CollectorsActions.getCollectorActions(this.props.collector.id).then(this._resetButton); 83 | } 84 | }, 85 | 86 | render() { 87 | return ( 88 | 91 | ); 92 | }, 93 | }); 94 | 95 | export default CollectorsImportButton; 96 | -------------------------------------------------------------------------------- /src/web/collectors/CollectorsPage.css: -------------------------------------------------------------------------------- 1 | :local(.sidecarModal) { 2 | font-size: 14px; 3 | } 4 | 5 | :local(.sidecarModal) div { 6 | padding: 10px 15px; 7 | } 8 | 9 | :local(.sidecarModal) h4 { 10 | font-size: 16px; 11 | font-weight: 500; 12 | margin-bottom: 5px; 13 | } 14 | 15 | :local(.sidecarModal) p { 16 | margin-bottom: 15px; 17 | } 18 | -------------------------------------------------------------------------------- /src/web/collectors/CollectorsPage.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | import DocsHelper from 'util/DocsHelper'; 18 | 19 | import React from 'react'; 20 | import { Link, LinkContainer } from 'components/common/router'; 21 | import { Button, Col, Modal, Row } from 'components/bootstrap'; 22 | import { DocumentTitle, PageHeader } from 'components/common'; 23 | import DocumentationLink from 'components/support/DocumentationLink'; 24 | import { BootstrapModalWrapper } from 'components/bootstrap'; 25 | import Routes from 'routing/Routes'; 26 | 27 | import CollectorList from './CollectorsList'; 28 | import style from './CollectorsPage.css'; 29 | import CollectorsPageNavigation from './CollectorsPageNavigation'; 30 | 31 | class CollectorsPage extends React.Component { 32 | 33 | constructor(props) { 34 | super(props); 35 | 36 | this.state = { 37 | showModal: false, 38 | }; 39 | } 40 | 41 | openModal = () => { 42 | this.setState({ showModal: true }); 43 | }; 44 | 45 | closeModal = () => { 46 | this.setState({ showModal: false }); 47 | }; 48 | 49 | renderModal = () => { 50 | return ( 51 | 54 | 55 | New Graylog Sidecar 56 | 57 | 58 |

59 | We listened to your feedback and have been working on the new Graylog Sidecar. Here is what you can 60 | expect from it: 61 |

62 | 63 |
64 |

Works with any log collector

65 |

66 | Graylog Sidecar includes support for some popular log collectors out of the box. Now you can also 67 | add any other log collector that you want to manage through a Sidecar. 68 |

69 |

Manage your Sidecars from within the Graylog Web Interface

70 |

71 | Use the Web Interface to get an overview of your Sidecar fleet from your browser. The new administration 72 | page also lets you manage any Sidecars or Collectors registered into that Graylog instance. 73 |

74 |

Use any configuration option

75 |

76 | Write Collector's Configurations in the Graylog Web Interface as you would do in your favourite 77 | editor. Do you have common configuration blocks that you want to reuse? You can include any Configuration 78 | inside another Configuration to avoid duplicating it. 79 |

80 |

Content Packs support

81 |

82 | Create and share Content Packs with your Collectors and Configurations, or install Content Packs from 83 | other community members that will expand your Sidecars with new Collectors. 84 |

85 |

Integrated in the product

86 |

Graylog Sidecar is now included in Graylog, no need to manage any additional plugins.

87 |

Faster and more robust

88 |

89 | We have also been busy to ensure everything is fast and resilient, so you can have a great experience. 90 |

91 |
92 | 93 |

94 | Do you want to know more about the new Graylog Sidecar? Read the{' '} 95 | for more information. 96 |

97 |
98 | 99 | 100 | 101 | 102 |
103 | ); 104 | }; 105 | 106 | render() { 107 | const lifecycleMessage = ( 108 | The Graylog Collector plugin is discontinued and has been superseded by the new Sidecars. 109 | ); 110 | 111 | return ( 112 | 113 | 114 | 121 | 122 | The Graylog collectors can reliably forward contents of log files or Windows EventLog from your servers. 123 |
124 | There is a new version of Graylog Collector and it is called{' '} 125 | Graylog Sidecar.  126 | What's new? 127 |
128 |
129 | 130 | {this.renderModal()} 131 | 132 | 133 | 134 | 135 | 136 | 137 |
138 | ); 139 | } 140 | } 141 | 142 | export default CollectorsPage; 143 | -------------------------------------------------------------------------------- /src/web/collectors/CollectorsPageNavigation.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | import * as React from 'react'; 18 | 19 | import PageNavigation from 'components/common/PageNavigation'; 20 | import Routes from 'routing/Routes'; 21 | import { Row } from 'components/bootstrap'; 22 | 23 | const CollectorsPageNavigation = () => { 24 | const NAV_ITEMS = [ 25 | { title: 'Overview', path: Routes.pluginRoute('SYSTEM_COLLECTORS'), exactPathMatch: true }, 26 | { title: 'Manage Configurations', path: Routes.pluginRoute('SYSTEM_COLLECTORS_CONFIGURATIONS') }, 27 | ]; 28 | 29 | return ( 30 | 31 | 32 | 33 | ) 34 | }; 35 | 36 | export default CollectorsPageNavigation; 37 | -------------------------------------------------------------------------------- /src/web/collectors/CollectorsRestartButton.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | import PropTypes from 'prop-types'; 18 | import React from 'react'; 19 | import createReactClass from 'create-react-class'; 20 | 21 | import { Button } from 'components/bootstrap'; 22 | import CollectorsActions from 'collectors/CollectorsActions'; 23 | 24 | const CollectorsRestartButton = createReactClass({ 25 | displayName: 'CollectorsRestartButton', 26 | 27 | propTypes: { 28 | collector: PropTypes.object.isRequired, 29 | backend: PropTypes.string.isRequired, 30 | }, 31 | 32 | getInitialState() { 33 | return { 34 | disabled: false, 35 | }; 36 | }, 37 | 38 | componentDidMount() { 39 | this.interval = setInterval(this._refreshButtonState, this.BUTTON_REFRESH); 40 | }, 41 | 42 | componentWillUnmount() { 43 | if (this.interval) { 44 | clearInterval(this.interval); 45 | } 46 | }, 47 | 48 | BUTTON_REFRESH: 2 * 1000, 49 | 50 | _handleRestart() { 51 | if (window.confirm('You are about to restart the collector process. Are you sure?')) { 52 | CollectorsActions.restartCollectorBackend.triggerPromise(this.props.collector.id, this.props.backend).then(this._disableButton); 53 | } 54 | }, 55 | 56 | _disableButton() { 57 | this.setState({ disabled: true }); 58 | }, 59 | 60 | _resetButton(actions) { 61 | let reset = true; 62 | if (actions) { 63 | actions.forEach((action) => { 64 | if (action.backend === this.props.backend && action.properties.restart === true) { 65 | reset = false; 66 | } 67 | }); 68 | } 69 | if (reset) { 70 | this.setState({ disabled: false }); 71 | } 72 | }, 73 | 74 | _refreshButtonState() { 75 | if (this.state.disabled) { 76 | CollectorsActions.getCollectorActions.triggerPromise(this.props.collector.id).then(this._resetButton); 77 | } 78 | }, 79 | 80 | render() { 81 | return ( 82 | 85 | ); 86 | }, 87 | }); 88 | 89 | export default CollectorsRestartButton; 90 | -------------------------------------------------------------------------------- /src/web/collectors/CollectorsStatusFileList.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | import PropTypes from 'prop-types'; 18 | import React from 'react'; 19 | 20 | import { DataTable, Spinner, Timestamp } from 'components/common'; 21 | 22 | class CollectorsStatusFileList extends React.Component { 23 | static propTypes = { 24 | files: PropTypes.array.isRequired, 25 | }; 26 | 27 | _headerCellFormatter = (header) => { 28 | return {header}; 29 | }; 30 | 31 | _activityFormatter = (time) => { 32 | const now = new Date().getTime(); 33 | const modDate = new Date(time).getTime(); 34 | if (modDate > (now - 60000)) { 35 | return ('info'); 36 | } 37 | return (''); 38 | }; 39 | 40 | _dirFormatter = (file) => { 41 | if (file.is_dir) { 42 | return (  {file.path}); 43 | } 44 | return (  {file.path}); 45 | }; 46 | 47 | _fileListFormatter = (file) => { 48 | const format = 'YYYY-MM-DD HH:mm:ss'; 49 | 50 | return ( 51 | 52 | 53 | {file.size} 54 | {this._dirFormatter(file)} 55 | 56 | ); 57 | }; 58 | 59 | render() { 60 | const filterKeys = []; 61 | const headers = ['Modified', 'Size', 'Path']; 62 | 63 | return ( 64 |
65 | 73 |
74 | ); 75 | } 76 | } 77 | 78 | export default CollectorsStatusFileList; 79 | -------------------------------------------------------------------------------- /src/web/collectors/CollectorsStore.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | import Reflux from 'reflux'; 18 | import URLUtils from 'util/URLUtils'; 19 | import UserNotification from 'util/UserNotification'; 20 | import fetch, { fetchPeriodically } from 'logic/rest/FetchProvider'; 21 | 22 | import CollectorsActions from './CollectorsActions'; 23 | 24 | const CollectorsStore = Reflux.createStore({ 25 | listenables: [CollectorsActions], 26 | sourceUrl: '/plugins/org.graylog.plugins.collector/collectors', 27 | collectors: undefined, 28 | 29 | init() { 30 | this.trigger({ collectors: this.collectors }); 31 | }, 32 | 33 | list() { 34 | const promise = fetchPeriodically('GET', URLUtils.qualifyUrl(this.sourceUrl)); 35 | promise 36 | .then( 37 | (response) => { 38 | this.collectors = response.collectors; 39 | this.trigger({ collectors: this.collectors }); 40 | 41 | return this.collectors; 42 | }, 43 | (error) => { 44 | UserNotification.error(`Fetching Collectors failed with status: ${error}`, 45 | 'Could not retrieve Collectors'); 46 | }, 47 | ); 48 | CollectorsActions.list.promise(promise); 49 | }, 50 | 51 | getCollector(collectorId) { 52 | const promise = fetchPeriodically('GET', URLUtils.qualifyUrl(`${this.sourceUrl}/${collectorId}`)); 53 | promise 54 | .catch( 55 | (error) => { 56 | UserNotification.error(`Fetching Collector failed with status: ${error}`, 57 | 'Could not retrieve Collector'); 58 | }, 59 | ); 60 | CollectorsActions.getCollector.promise(promise); 61 | }, 62 | 63 | restartCollectorBackend(collectorId, backend) { 64 | const action = {}; 65 | action.backend = backend; 66 | action.properties = {}; 67 | action.properties.restart = true; 68 | const promise = fetch('PUT', URLUtils.qualifyUrl(`${this.sourceUrl}/${collectorId}/action`), [action]); 69 | promise 70 | .catch( 71 | (error) => { 72 | UserNotification.error(`Restarting Collector failed with status: ${error}`, 73 | 'Could not restart Collector'); 74 | }, 75 | ); 76 | CollectorsActions.restartCollectorBackend.promise(promise); 77 | }, 78 | 79 | importCollectorConfiguration(collectorId, backend) { 80 | const action = {}; 81 | action.backend = backend; 82 | action.properties = {}; 83 | action.properties.import = true; 84 | const promise = fetch('PUT', URLUtils.qualifyUrl(`${this.sourceUrl}/${collectorId}/action`), [action]); 85 | promise 86 | .catch( 87 | (error) => { 88 | UserNotification.error(`Import collector configuration failed with status: ${error}`, 89 | 'Could not import Configuration'); 90 | }, 91 | ); 92 | CollectorsActions.importCollectorConfiguration.promise(promise); 93 | }, 94 | 95 | getCollectorActions(collectorId) { 96 | const promise = fetchPeriodically('GET', URLUtils.qualifyUrl(`${this.sourceUrl}/${collectorId}/action`)); 97 | promise 98 | .catch( 99 | (error) => { 100 | UserNotification.error(`Fetching Collector actions failed with status: ${error}`, 101 | 'Could not retrieve Collector actions'); 102 | }, 103 | ); 104 | CollectorsActions.getCollectorActions.promise(promise); 105 | }, 106 | }); 107 | 108 | export default CollectorsStore; 109 | -------------------------------------------------------------------------------- /src/web/collectors/ImportsHelperModal.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | import React from 'react'; 18 | import PropTypes from 'prop-types'; 19 | 20 | import { Link } from 'components/common/router'; 21 | import { Alert, Button, Modal } from 'components/bootstrap'; 22 | import BootstrapModalWrapper from 'components/bootstrap/BootstrapModalWrapper'; 23 | import Routes from 'routing/Routes'; 24 | 25 | class ImportsHelperModal extends React.Component { 26 | render() { 27 | return ( 28 | 30 | 31 | Configuration Import 32 | 33 | 34 | 35 |   36 | Configuration was imported successfully, continue with the new Sidecar Configurations and use it as a base to create new configurations. 37 | 38 | 39 | 40 | 41 | 42 | 43 | ); 44 | } 45 | } 46 | 47 | ImportsHelperModal.propTypes = { 48 | showModal: PropTypes.bool.isRequired, 49 | onHide: PropTypes.func.isRequired, 50 | }; 51 | 52 | export default ImportsHelperModal; 53 | -------------------------------------------------------------------------------- /src/web/configurations/CollectorConfigurationsActions.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | import Reflux from 'reflux'; 18 | 19 | const CollectorConfigurationsActions = Reflux.createActions({ 20 | list: { asyncResult: true }, 21 | getConfiguration: { asyncResult: true }, 22 | createConfiguration: { asyncResult: true }, 23 | updateConfiguration: { asyncResult: true }, 24 | saveTags: { asyncResult: true }, 25 | saveOutput: { asyncResult: true }, 26 | saveInput: { asyncResult: true }, 27 | saveSnippet: { asyncResult: true }, 28 | copyConfiguration: { asyncResult: true }, 29 | copyOutput: { asyncResult: true }, 30 | copyInput: { asyncResult: true }, 31 | copySnippet: { asyncResult: true }, 32 | delete: { asyncResult: true }, 33 | deleteOutput: { asyncResult: true }, 34 | deleteInput: { asyncResult: true }, 35 | deleteSnippet: { asyncResult: true }, 36 | updateTags: { asyncResult: true }, 37 | listTags: { asyncResult: true }, 38 | }); 39 | 40 | export default CollectorConfigurationsActions; 41 | -------------------------------------------------------------------------------- /src/web/configurations/ConfigurationRow.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | import PropTypes from 'prop-types'; 18 | import React from 'react'; 19 | import createReactClass from 'create-react-class'; 20 | import { LinkContainer } from 'components/common/router'; 21 | 22 | import { Button } from 'components/bootstrap'; 23 | import Routes from 'routing/Routes'; 24 | import style from 'styles/CollectorStyles.lazy.css'; 25 | 26 | import EditConfigurationModal from './EditConfigurationModal'; 27 | import CopyConfigurationModal from './CopyConfigurationModal'; 28 | 29 | const ConfigurationRow = createReactClass({ 30 | displayName: 'ConfigurationRow', 31 | 32 | propTypes: { 33 | configuration: PropTypes.object.isRequired, 34 | onUpdate: PropTypes.func.isRequired, 35 | onCopy: PropTypes.func.isRequired, 36 | validateConfiguration: PropTypes.func.isRequired, 37 | onDelete: PropTypes.func.isRequired, 38 | }, 39 | 40 | componentDidMount() { 41 | style.use(); 42 | }, 43 | 44 | componentWillUnmount() { 45 | style.unuse(); 46 | }, 47 | 48 | _handleClick() { 49 | const { configuration } = this.props; 50 | if (window.confirm(`You are about to delete configuration "${configuration.name}". Are you sure?`)) { 51 | this.props.onDelete(configuration); 52 | } 53 | }, 54 | 55 | render() { 56 | const { configuration } = this.props; 57 | const tagBadges = configuration.tags.map((tag) => { 58 | return {tag}; 59 | }); 60 | 61 | return ( 62 | 63 | 64 | 65 | {configuration.name} 66 | 67 | 68 | 69 | {tagBadges} 70 | 71 | 72 | 75 |   76 | 77 |   78 | 81 | 82 | 83 | ); 84 | }, 85 | }); 86 | 87 | export default ConfigurationRow; 88 | -------------------------------------------------------------------------------- /src/web/configurations/ConfigurationsList.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | import React from 'react'; 18 | import createReactClass from 'create-react-class'; 19 | import Reflux from 'reflux'; 20 | 21 | import { DataTable, Spinner } from 'components/common'; 22 | import style from 'styles/CollectorStyles.lazy.css'; 23 | 24 | import CollectorConfigurationsStore from './CollectorConfigurationsStore'; 25 | import ConfigurationRow from './ConfigurationRow'; 26 | import CollectorConfigurationsActions from './CollectorConfigurationsActions'; 27 | import EditConfigurationModal from './EditConfigurationModal'; 28 | 29 | const ConfigurationsList = createReactClass({ 30 | displayName: 'ConfigurationsList', 31 | mixins: [Reflux.connect(CollectorConfigurationsStore)], 32 | 33 | componentDidMount() { 34 | style.use(); 35 | this._reloadConfiguration(); 36 | }, 37 | 38 | componentWillUnmount() { 39 | style.unuse(); 40 | }, 41 | 42 | _reloadConfiguration() { 43 | CollectorConfigurationsActions.list.triggerPromise().then((configurations) => { 44 | const tags = configurations 45 | .map(configuration => configuration.tags) 46 | .reduce((uniqueTags, currentTags) => { 47 | currentTags.forEach((tag) => { 48 | if (uniqueTags.indexOf(tag) === -1) { 49 | uniqueTags.push(tag); 50 | } 51 | }); 52 | 53 | return uniqueTags; 54 | }, []); 55 | this.setState({ tags }); 56 | }); 57 | }, 58 | 59 | _validConfigurationName(name) { 60 | // Check if configurations already contain a configuration with the given name. 61 | return !this.state.configurations.some(configuration => configuration.name === name); 62 | }, 63 | 64 | _createConfiguration(configuration, callback) { 65 | CollectorConfigurationsActions.createConfiguration.triggerPromise(configuration.name) 66 | .then(() => { 67 | callback(); 68 | this._reloadConfiguration(); 69 | }); 70 | }, 71 | 72 | _updateConfiguration(configuration, callback) { 73 | CollectorConfigurationsActions.updateConfiguration.triggerPromise(configuration) 74 | .then(() => { 75 | callback(); 76 | this._reloadConfiguration(); 77 | }); 78 | }, 79 | 80 | _copyConfiguration(configuration, name, callback) { 81 | CollectorConfigurationsActions.copyConfiguration.triggerPromise(configuration, name) 82 | .then(() => { 83 | callback(); 84 | this._reloadConfiguration(); 85 | }); 86 | }, 87 | 88 | _onDelete(configuration) { 89 | CollectorConfigurationsActions.delete.triggerPromise(configuration) 90 | .then(() => { 91 | this._reloadConfiguration(); 92 | }); 93 | }, 94 | 95 | _headerCellFormatter(header) { 96 | const className = (header === 'Actions' ? 'actions' : ''); 97 | return {header}; 98 | }, 99 | 100 | _collectorConfigurationFormatter(configuration) { 101 | return ( 102 | 108 | ); 109 | }, 110 | 111 | _isLoading() { 112 | return !this.state.configurations; 113 | }, 114 | 115 | render() { 116 | if (this._isLoading()) { 117 | return ; 118 | } 119 | 120 | const headers = ['Configuration', 'Tags', 'Actions']; 121 | const filterKeys = ['name', 'id']; 122 | 123 | return ( 124 |
125 | 137 |
138 | 141 |
142 |
143 |
144 | ); 145 | }, 146 | }); 147 | 148 | export default ConfigurationsList; 149 | -------------------------------------------------------------------------------- /src/web/configurations/ConfigurationsPage.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | import React from 'react'; 18 | 19 | import DocsHelper from 'util/DocsHelper'; 20 | import { Row, Col, Button } from 'components/bootstrap'; 21 | import { DocumentTitle, PageHeader } from 'components/common'; 22 | 23 | import ConfigurationsList from './ConfigurationsList'; 24 | import CollectorsPageNavigation from '../collectors/CollectorsPageNavigation'; 25 | 26 | const LifecycleMessage = () => ( 27 | The Graylog Collector plugin is discontinued and has been superseded by the new Sidecars. 28 | ); 29 | 30 | const ConfigurationsPage = () => ( 31 | 32 | 33 | } 36 | documentationLink={{ 37 | title: 'Sidecar documentation', 38 | path: DocsHelper.PAGES.COLLECTOR_SIDECAR, 39 | }}> 40 | 41 | The Collector Sidecar runs next to your favourite log collector and configures it for you. Here you can 42 | manage the Sidecar configurations. 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | ); 53 | 54 | export default ConfigurationsPage; 55 | -------------------------------------------------------------------------------- /src/web/configurations/CopyConfigurationModal.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | import PropTypes from 'prop-types'; 18 | import React from 'react'; 19 | 20 | import { Button } from 'components/bootstrap'; 21 | import { BootstrapModalForm, Input } from 'components/bootstrap'; 22 | 23 | class CopyConfigurationModal extends React.Component { 24 | static propTypes = { 25 | id: PropTypes.string, 26 | copyConfiguration: PropTypes.func.isRequired, 27 | validConfigurationName: PropTypes.func.isRequired, 28 | }; 29 | 30 | static defaultProps = { 31 | id: '', 32 | name: '', 33 | }; 34 | 35 | state = { 36 | id: this.props.id, 37 | name: '', 38 | error: false, 39 | error_message: '', 40 | showModal: false, 41 | }; 42 | 43 | openModal = () => { 44 | this.setState({ showModal: true }); 45 | }; 46 | 47 | _getId = (prefixIdName) => { 48 | return prefixIdName + this.state.name; 49 | }; 50 | 51 | _closeModal = () => { 52 | this.setState({ showModal: false }); 53 | }; 54 | 55 | _saved = () => { 56 | this._closeModal(); 57 | this.setState({ name: '' }); 58 | }; 59 | 60 | _save = () => { 61 | const configuration = this.state; 62 | 63 | if (!configuration.error) { 64 | this.props.copyConfiguration(this.props.id, this.state.name, this._saved); 65 | } 66 | }; 67 | 68 | _changeName = (event) => { 69 | this.setState({ name: event.target.value }); 70 | }; 71 | 72 | render() { 73 | return ( 74 | 75 | 80 | 85 |
86 | 95 |
96 |
97 |
98 | ); 99 | } 100 | } 101 | 102 | export default CopyConfigurationModal; 103 | -------------------------------------------------------------------------------- /src/web/configurations/EditConfigurationModal.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | import PropTypes from 'prop-types'; 18 | import React from 'react'; 19 | import createReactClass from 'create-react-class'; 20 | 21 | import { Button } from 'components/bootstrap'; 22 | import { BootstrapModalForm, Input } from 'components/bootstrap'; 23 | import ObjectUtils from 'util/ObjectUtils'; 24 | 25 | const EditConfigurationModal = createReactClass({ 26 | displayName: 'EditConfigurationModal', 27 | 28 | propTypes: { 29 | configuration: PropTypes.object, 30 | create: PropTypes.bool, 31 | updateConfiguration: PropTypes.func.isRequired, 32 | validConfigurationName: PropTypes.func.isRequired, 33 | }, 34 | 35 | getDefaultProps() { 36 | return { 37 | configuration: { name: '' }, 38 | }; 39 | }, 40 | 41 | getInitialState() { 42 | return { 43 | configuration: ObjectUtils.clone(this.props.configuration), 44 | error: false, 45 | error_message: '', 46 | showModal: false, 47 | }; 48 | }, 49 | 50 | openModal() { 51 | this.setState({ showModal: true }); 52 | }, 53 | 54 | _closeModal() { 55 | this.setState({ showModal: false }); 56 | }, 57 | 58 | _getId(prefixIdName) { 59 | return prefixIdName + this.state.configuration.name; 60 | }, 61 | 62 | _saved() { 63 | this._closeModal(); 64 | this.setState(this.getInitialState()); 65 | }, 66 | 67 | _save() { 68 | const { configuration } = this.state; 69 | 70 | if (!this.state.error) { 71 | this.props.updateConfiguration(configuration, this._saved); 72 | } 73 | }, 74 | 75 | _changeName(event) { 76 | const name = event.target.value; 77 | const newConfiguration = ObjectUtils.clone(this.state.configuration); 78 | newConfiguration.name = name; 79 | 80 | if (!this.props.validConfigurationName(name)) { 81 | this.setState({ 82 | configuration: newConfiguration, 83 | error: true, 84 | error_message: 'Configuration with that name already exists!', 85 | }); 86 | } else { 87 | this.setState({ configuration: newConfiguration, error: false, error_message: '' }); 88 | } 89 | }, 90 | 91 | render() { 92 | return ( 93 | 94 | 99 | 105 |
106 | 115 |
116 |
117 |
118 | ); 119 | }, 120 | }); 121 | 122 | export default EditConfigurationModal; 123 | -------------------------------------------------------------------------------- /src/web/index.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | // eslint-disable-next-line no-unused-vars 18 | import './webpack-entry'; 19 | 20 | import AppConfig from 'util/AppConfig'; 21 | import { PluginManifest, PluginStore } from 'graylog-web-plugin/plugin'; 22 | 23 | import CollectorsPage from 'collectors/CollectorsPage'; 24 | import CollectorsStatusPage from 'collectors/CollectorsStatusPage'; 25 | import ConfigurationsPage from 'configurations/ConfigurationsPage'; 26 | import CollectorConfigurationPage from 'collector-configuration/CollectorConfigurationPage'; 27 | import CollectorSystemConfiguration from 'system-configuration/CollectorSystemConfiguration'; 28 | import packageJson from '../../package.json'; 29 | 30 | const manifest = AppConfig.isCloud() ? {} : new PluginManifest(packageJson, { 31 | routes: [ 32 | { path: '/system/collectors', component: CollectorsPage }, 33 | { path: '/system/collectors/:id/status', component: CollectorsStatusPage }, 34 | { path: '/system/collectors/configurations', component: ConfigurationsPage }, 35 | { path: '/system/collectors/configurations/:id', component: CollectorConfigurationPage }, 36 | ], 37 | 38 | // Adding an element to the top navigation pointing to /sample named "Sample": 39 | 40 | systemnavigation: [ 41 | { path: '/system/collectors', description: 'Collectors (legacy)', permissions: 'collectors:read' }, 42 | ], 43 | 44 | systemConfigurations: [ 45 | { 46 | component: CollectorSystemConfiguration, 47 | configType: 'org.graylog.plugins.collector.system.CollectorSystemConfiguration', 48 | }, 49 | ], 50 | }); 51 | 52 | PluginStore.register(manifest); 53 | -------------------------------------------------------------------------------- /src/web/styles/CollectorStyles.lazy.css: -------------------------------------------------------------------------------- 1 | .collector-os { 2 | margin-right: 5px; 3 | margin-left: 2px; 4 | } 5 | 6 | .name { 7 | width: 300px; 8 | } 9 | 10 | #collector-configurations-list th.actions, td.actions { 11 | width: 150px; 12 | } 13 | 14 | #collector-outputs-list th.actions, td.actions { 15 | width: 150px; 16 | } 17 | 18 | #collector-inputs-list th.actions, td.actions { 19 | width: 150px; 20 | } 21 | 22 | #collector-snippets-list th.actions, td.actions { 23 | width: 150px; 24 | } 25 | 26 | .deflist { 27 | margin-top: 10px; 28 | } 29 | 30 | .deflist dt { 31 | float: left; 32 | clear: left; 33 | } 34 | 35 | .deflist dd { 36 | margin-left: 160px; 37 | } 38 | 39 | .top-margin { 40 | margin-top: 10px; 41 | } 42 | 43 | hr.separator { 44 | margin-top: 10px; 45 | margin-bottom: 5px; 46 | } 47 | 48 | .collector-name { 49 | word-break: break-all; 50 | } 51 | 52 | .configuration-tag { 53 | font-weight: normal; 54 | margin-right: 2px; 55 | } 56 | 57 | .configuration-tag-sm { 58 | font-size: 80%; 59 | } 60 | -------------------------------------------------------------------------------- /src/web/webpack-entry.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | import URI from 'urijs'; 18 | 19 | import AppConfig from 'util/AppConfig'; 20 | 21 | // The webpack-dev-server serves the assets from "/" 22 | const assetPrefix = AppConfig.gl2DevMode() ? '/' : '/assets/plugin/org.graylog.plugins.collector.CollectorPlugin/'; 23 | 24 | // If app prefix was not set, we need to tell webpack to load chunks from root instead of the relative URL path 25 | __webpack_public_path__ = URI.joinPaths(AppConfig.gl2AppPathPrefix(), assetPrefix).path() || assetPrefix; 26 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Graylog, Inc. 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the Server Side Public License, version 1, 6 | * as published by MongoDB, Inc. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * Server Side Public License for more details. 12 | * 13 | * You should have received a copy of the Server Side Public License 14 | * along with this program. If not, see 15 | * . 16 | */ 17 | const PluginWebpackConfig = require('graylog-web-plugin').PluginWebpackConfig; 18 | const loadBuildConfig = require('graylog-web-plugin').loadBuildConfig; 19 | const path = require('path'); 20 | 21 | module.exports = new PluginWebpackConfig(__dirname, 'org.graylog.plugins.collector.CollectorPlugin', loadBuildConfig(path.resolve(__dirname, './build.config')), { 22 | // Here goes your additional webpack configuration. 23 | }); 24 | --------------------------------------------------------------------------------