├── .gitignore ├── .travis.yml ├── GETTING-STARTED.md ├── README.md ├── build.config.js ├── package.json ├── pom.xml ├── src ├── deb │ └── control │ │ └── control ├── main │ ├── java │ │ └── org │ │ │ └── graylog │ │ │ └── plugins │ │ │ └── sample │ │ │ ├── SampleMetaData.java │ │ │ ├── SampleModule.java │ │ │ ├── SamplePlugin.java │ │ │ ├── alerts │ │ │ ├── SampleAlertCondition.java │ │ │ └── SampleAlertNotification.java │ │ │ └── decorator │ │ │ └── SampleDecorator.java │ └── resources │ │ ├── META-INF │ │ └── services │ │ │ └── org.graylog2.plugin.Plugin │ │ └── org.graylog.plugins.graylog-plugin-sample │ │ └── graylog-plugin.properties └── web │ ├── index.jsx │ └── pages │ └── SamplePage.jsx └── webpack.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | *.iml 3 | *.ipr 4 | *.iws 5 | .classpath 6 | .project 7 | .settings/ 8 | target/ 9 | dependency-reduced-pom.xml 10 | node_modules 11 | node 12 | build 13 | build.config.js 14 | 15 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: java 3 | jdk: 4 | - oraclejdk8 5 | addons: 6 | apt: 7 | packages: 8 | - libxml2-utils 9 | - rpm 10 | before_install: 11 | # Get Graylog version from Maven POM (property: "graylog.version") 12 | - export GRAYLOG_VERSION=$(xmllint --xpath '/*[local-name()="project"]/*[local-name()="properties"]/*[local-name()="graylog.version"]/text()' pom.xml) 13 | # Checkout desired Graylog version 14 | - echo "Checking out Graylog ${GRAYLOG_VERSION}" 15 | - git clone --depth 1 --branch "${GRAYLOG_VERSION}" https://github.com/Graylog2/graylog2-server.git ../graylog2-server 16 | # Build Graylog web interface 17 | - pushd ../graylog2-server 18 | - mvn generate-resources -pl graylog2-server -B -V 19 | - popd 20 | 21 | # For automatic deployment, uncomment the lines below. 22 | # See https://docs.travis-ci.com/user/deployment/releases/ for details. 23 | #before_deploy: 24 | # - find . -type f -name 'original-*.jar' -delete 25 | # - mvn jdeb:jdeb 26 | # - mvn rpm:rpm 27 | #deploy: 28 | # provider: releases 29 | # api_key: 30 | # secure: 31 | # file_glob: true 32 | # file: 33 | # - "**/target/*.jar" 34 | # - "**/target/*.deb" 35 | # - "**/target/**/*.rpm" 36 | # skip_cleanup: true 37 | # on: 38 | # tags: true 39 | # jdk: oraclejdk8 40 | -------------------------------------------------------------------------------- /GETTING-STARTED.md: -------------------------------------------------------------------------------- 1 | Getting started with your new Graylog plugin 2 | ============================================ 3 | 4 | Welcome to your new Graylog plugin! 5 | 6 | Please refer to http://docs.graylog.org/en/latest/pages/plugins.html for documentation on how to write 7 | plugins for Graylog. 8 | 9 | Travis CI 10 | --------- 11 | 12 | There is a `.travis.yml` template in this project which is prepared to automatically 13 | deploy the plugin artifacts (JAR, DEB, RPM) to GitHub releases. 14 | 15 | You just have to add your encrypted GitHub access token to the `.travis.yml`. 16 | The token can be generated in your [GitHub personal access token settings](https://github.com/settings/tokens). 17 | 18 | Before Travis CI works, you have to enable it. Install the Travis CI command line 19 | application and execute `travis enable`. 20 | 21 | To encrypt your GitHub access token you can use `travis encrypt`. 22 | 23 | Alternatively you can use `travis setup -f releases` to automatically create a GitHub 24 | access token and add it to the `.travis.yml` file. **Attention:** doing this 25 | will replace some parts of the `.travis.yml` file and you have to restore previous 26 | settings. 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Sample Plugin for Graylog 2 | 3 | This repository is intended to be used to follow the [Plugin API documentation](https://go2docs.graylog.org/5-1/what_more_can_graylog_do_for_me/plugins.html) for Graylog. 4 | It contains no useful functionality beyond illustrating the various extension points one can use for customizing and extending Graylog. 5 | 6 | __Important: Do not use this repository as a boilerplate for a new graylog plugin.\ 7 | Please use the maven archetype to create a plugin skeleton, as [described in the Plugin API documentation](https://go2docs.graylog.org/5-1/what_more_can_graylog_do_for_me/plugins.html#WritingPlugins).__ 8 | 9 | 10 | [![Build Status](https://travis-ci.org/Graylog2/graylog-plugin-sample.svg?branch=master)](https://travis-ci.org/Graylog2/graylog-plugin-sample) 11 | 12 | __Use this paragraph to enter a description of your plugin.__ 13 | 14 | **Required Graylog version:** 5.1 and later 15 | 16 | Installation 17 | ------------ 18 | 19 | [Download the plugin](https://github.com/Graylog2/graylog-plugin-sample/releases) 20 | and place the `.jar` file in your Graylog plugin directory. The plugin directory 21 | is the `plugins/` folder relative from your `graylog-server` directory by default 22 | and can be configured in your `graylog.conf` file. 23 | 24 | Restart `graylog-server` and you are done. 25 | 26 | Development 27 | ----------- 28 | 29 | You can improve your development experience for the web interface part of your plugin 30 | dramatically by making use of hot reloading. To do this, do the following: 31 | 32 | * `git clone https://github.com/Graylog2/graylog2-server.git` 33 | * `cd graylog2-server/graylog2-web-interface` 34 | * `ln -s $YOURPLUGIN plugin/` 35 | * `npm install && npm start` 36 | 37 | Usage 38 | ----- 39 | 40 | __Use this paragraph to document the usage of your plugin__ 41 | 42 | 43 | Getting started 44 | --------------- 45 | 46 | This project is using Maven 3 and requires Java 7 or higher. 47 | 48 | * Clone this repository. 49 | * Run `mvn package` to build a JAR file. 50 | * Optional: Run `mvn jdeb:jdeb` and `mvn rpm:rpm` to create a DEB and RPM package respectively. 51 | * Copy generated JAR file in target directory to your Graylog plugin directory. 52 | * Restart the Graylog. 53 | 54 | Plugin Release 55 | -------------- 56 | 57 | We are using the maven release plugin: 58 | 59 | ``` 60 | $ mvn release:prepare 61 | [...] 62 | $ mvn release:perform 63 | ``` 64 | 65 | This sets the version numbers, creates a tag and pushes to GitHub. Travis CI will build the release artifacts and upload to GitHub automatically. 66 | -------------------------------------------------------------------------------- /build.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | module.exports = { 4 | // Make sure that this is the correct path to the web interface part of the Graylog server repository. 5 | web_src_path: path.resolve(__dirname, '../graylog2-server/graylog2-web-interface'), 6 | }; 7 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Sample", 3 | "version": "5.2.0", 4 | "description": "Graylog Example plugin", 5 | "repository": { 6 | "type": "git", 7 | "url": "https://github.com/Graylog2/graylog-plugin-sample" 8 | }, 9 | "scripts": { 10 | "build": "webpack --bail" 11 | }, 12 | "keywords": [ 13 | "graylog" 14 | ], 15 | "author": "Graylog, Inc. ", 16 | "license": "GPL-3.0", 17 | "dependencies": { 18 | }, 19 | "devDependencies": { 20 | "graylog-web-plugin": "file:../graylog2-server/graylog2-web-interface/packages/graylog-web-plugin" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | 3.1 8 | 9 | 10 | 11 | org.graylog.plugins 12 | graylog-plugin-web-parent 13 | 5.2.0 14 | ../graylog2-server/graylog-plugin-parent/graylog-plugin-web-parent 15 | 16 | 17 | org.graylog.plugins 18 | graylog-plugin-sample 19 | 5.2.0-SNAPSHOT 20 | jar 21 | 22 | ${project.artifactId} 23 | Graylog ${project.artifactId} plugin. 24 | https://www.graylog.org 25 | 26 | 27 | 28 | Graylog, Inc 29 | hello@graylog.com 30 | 31 | 32 | 33 | 34 | scm:git:git@github.com:Graylog2/graylog-plugin-sample.git 35 | scm:git:git@github.com:Graylog2/graylog-plugin-sample.git 36 | https://github.com/Graylog2/graylog-plugin-sample 37 | HEAD 38 | 39 | 40 | 41 | UTF-8 42 | 1.8 43 | 1.8 44 | 45 | 46 | true 47 | true 48 | true 49 | true 50 | true 51 | 52 | 5.2.0 53 | 54 | 55 | 56 | 57 | sonatype-nexus-snapshots 58 | Sonatype Nexus Snapshots 59 | https://oss.sonatype.org/content/repositories/snapshots 60 | 61 | 62 | sonatype-nexus-staging 63 | Nexus Release Repository 64 | https://oss.sonatype.org/service/local/staging/deploy/maven2/ 65 | 66 | 67 | 68 | 69 | 70 | 71 | sonatype-nexus-snapshots 72 | Sonatype Nexus Snapshots 73 | https://oss.sonatype.org/content/repositories/snapshots 74 | 75 | false 76 | 77 | 78 | true 79 | 80 | 81 | 82 | sonatype-nexus-releases 83 | Sonatype Nexus Releases 84 | https://oss.sonatype.org/content/repositories/releases 85 | 86 | true 87 | 88 | 89 | false 90 | 91 | 92 | 93 | 94 | 95 | 96 | org.graylog2 97 | graylog2-server 98 | ${graylog.version} 99 | provided 100 | 101 | 102 | com.google.auto.value 103 | auto-value 104 | ${auto-value.version} 105 | provided 106 | 107 | 108 | 109 | 110 | 111 | build 112 | 113 | src/main/resources 114 | true 115 | 116 | 117 | 118 | 119 | maven-assembly-plugin 120 | 121 | true 122 | 123 | 124 | 125 | 126 | org.apache.maven.plugins 127 | maven-jar-plugin 128 | 129 | 130 | 131 | ${project.groupId}.${project.artifactId} 132 | 133 | 134 | 135 | 136 | 137 | 138 | org.apache.maven.plugins 139 | maven-shade-plugin 140 | 141 | false 142 | 143 | 144 | 145 | package 146 | 147 | shade 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | org.apache.maven.plugins 160 | maven-release-plugin 161 | 162 | true 163 | forked-path 164 | @{project.version} 165 | clean test 166 | package 167 | 168 | 169 | 170 | 171 | 172 | -------------------------------------------------------------------------------- /src/deb/control/control: -------------------------------------------------------------------------------- 1 | Package: [[name]] 2 | Version: [[version]] 3 | Architecture: all 4 | Maintainer: Graylog, Inc. 5 | Section: web 6 | Priority: optional 7 | Depends: graylog-server | graylog-radio 8 | Description: [[description]] 9 | -------------------------------------------------------------------------------- /src/main/java/org/graylog/plugins/sample/SampleMetaData.java: -------------------------------------------------------------------------------- 1 | package org.graylog.plugins.sample; 2 | 3 | import org.graylog2.plugin.PluginMetaData; 4 | import org.graylog2.plugin.ServerStatus; 5 | import org.graylog2.plugin.Version; 6 | 7 | import java.net.URI; 8 | import java.util.Collections; 9 | import java.util.Set; 10 | 11 | /** 12 | * Implement the PluginMetaData interface here. 13 | */ 14 | public class SampleMetaData implements PluginMetaData { 15 | private static final String PLUGIN_PROPERTIES = "org.graylog.plugins.graylog-plugin-sample/graylog-plugin.properties"; 16 | 17 | @Override 18 | public String getUniqueId() { 19 | return "org.graylog.plugins.sample.SamplePlugin"; 20 | } 21 | 22 | @Override 23 | public String getName() { 24 | return "Sample"; 25 | } 26 | 27 | @Override 28 | public String getAuthor() { 29 | return "Graylog, Inc "; 30 | } 31 | 32 | @Override 33 | public URI getURL() { 34 | return URI.create("https://github.com/Graylog2/graylog-plugin-sample"); 35 | } 36 | 37 | @Override 38 | public Version getVersion() { 39 | return Version.fromPluginProperties(getClass(), PLUGIN_PROPERTIES, "version", Version.from(0, 0, 0, "unknown")); 40 | } 41 | 42 | @Override 43 | public String getDescription() { 44 | // TODO Insert correct plugin description 45 | return "Description of Sample plugin"; 46 | } 47 | 48 | @Override 49 | public Version getRequiredVersion() { 50 | return Version.fromPluginProperties(getClass(), PLUGIN_PROPERTIES, "graylog.version", Version.from(0, 0, 0, "unknown")); 51 | } 52 | 53 | @Override 54 | public Set getRequiredCapabilities() { 55 | return Collections.emptySet(); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/org/graylog/plugins/sample/SampleModule.java: -------------------------------------------------------------------------------- 1 | package org.graylog.plugins.sample; 2 | 3 | import org.graylog.plugins.sample.alerts.SampleAlertCondition; 4 | import org.graylog.plugins.sample.alerts.SampleAlertNotification; 5 | import org.graylog.plugins.sample.decorator.SampleDecorator; 6 | import org.graylog2.plugin.PluginConfigBean; 7 | import org.graylog2.plugin.PluginModule; 8 | 9 | import java.util.Collections; 10 | import java.util.Set; 11 | 12 | /** 13 | * Extend the PluginModule abstract class here to add you plugin to the system. 14 | */ 15 | public class SampleModule extends PluginModule { 16 | /** 17 | * Returns all configuration beans required by this plugin. 18 | * 19 | * Implementing this method is optional. The default method returns an empty {@link Set}. 20 | */ 21 | @Override 22 | public Set getConfigBeans() { 23 | return Collections.emptySet(); 24 | } 25 | 26 | @Override 27 | protected void configure() { 28 | /* 29 | * Register your plugin types here. 30 | * 31 | * Examples: 32 | * 33 | * addMessageInput(Class); 34 | * addMessageFilter(Class); 35 | * addMessageOutput(Class); 36 | * addPeriodical(Class); 37 | * addAlarmCallback(Class); 38 | * addInitializer(Class); 39 | * addRestResource(Class); 40 | * 41 | * 42 | * Add all configuration beans returned by getConfigBeans(): 43 | * 44 | * addConfigBeans(); 45 | */ 46 | 47 | addAlarmCallback(SampleAlertNotification.class); 48 | 49 | addAlertCondition(SampleAlertCondition.class.getCanonicalName(), 50 | SampleAlertCondition.class, 51 | SampleAlertCondition.Factory.class); 52 | 53 | installSearchResponseDecorator(searchResponseDecoratorBinder(), 54 | SampleDecorator.class, 55 | SampleDecorator.Factory.class); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/org/graylog/plugins/sample/SamplePlugin.java: -------------------------------------------------------------------------------- 1 | package org.graylog.plugins.sample; 2 | 3 | import org.graylog2.plugin.Plugin; 4 | import org.graylog2.plugin.PluginMetaData; 5 | import org.graylog2.plugin.PluginModule; 6 | 7 | import java.util.Collection; 8 | import java.util.Collections; 9 | 10 | /** 11 | * Implement the Plugin interface here. 12 | */ 13 | public class SamplePlugin implements Plugin { 14 | @Override 15 | public PluginMetaData metadata() { 16 | return new SampleMetaData(); 17 | } 18 | 19 | @Override 20 | public Collection modules () { 21 | return Collections.singletonList(new SampleModule()); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/org/graylog/plugins/sample/alerts/SampleAlertCondition.java: -------------------------------------------------------------------------------- 1 | package org.graylog.plugins.sample.alerts; 2 | 3 | import com.google.inject.assistedinject.Assisted; 4 | 5 | import org.graylog2.alerts.AbstractAlertCondition; 6 | import org.graylog2.plugin.alarms.AlertCondition; 7 | import org.graylog2.plugin.configuration.ConfigurationRequest; 8 | import org.graylog2.plugin.streams.Stream; 9 | import org.joda.time.DateTime; 10 | 11 | import java.util.Map; 12 | 13 | import javax.annotation.Nullable; 14 | import javax.inject.Inject; 15 | 16 | public class SampleAlertCondition extends AbstractAlertCondition { 17 | 18 | @Inject 19 | public SampleAlertCondition(@Assisted Stream stream, 20 | @Nullable @Assisted("id") String id, 21 | @Assisted DateTime createdAt, 22 | @Assisted("userid") String creatorUserId, 23 | @Assisted Map parameters, 24 | @Assisted("title") @Nullable String title) { 25 | super(stream, id, SampleAlertCondition.class.getCanonicalName(), createdAt, creatorUserId, parameters, title); 26 | } 27 | 28 | @Override 29 | public String getDescription() { 30 | return "matches nothing"; 31 | } 32 | 33 | @Override 34 | public CheckResult runCheck() { 35 | return new AbstractAlertCondition.NegativeCheckResult(); 36 | } 37 | 38 | public interface Factory extends AlertCondition.Factory { 39 | SampleAlertCondition create(@Assisted Stream stream, 40 | @Assisted("id") String id, 41 | @Assisted DateTime createdAt, 42 | @Assisted("userid") String creatorUserId, 43 | @Assisted Map parameters, 44 | @Assisted("title") @Nullable String title); 45 | 46 | SampleAlertCondition.Config config(); 47 | 48 | SampleAlertCondition.Descriptor descriptor(); 49 | } 50 | 51 | public static class Config implements AlertCondition.Config { 52 | public Config() { 53 | } 54 | 55 | @Override 56 | public ConfigurationRequest getRequestedConfiguration() { 57 | final ConfigurationRequest configurationRequest = ConfigurationRequest.createWithFields(); 58 | configurationRequest.addFields(AbstractAlertCondition.getDefaultConfigurationFields()); 59 | 60 | return configurationRequest; 61 | } 62 | } 63 | 64 | public static class Descriptor extends AlertCondition.Descriptor { 65 | public Descriptor() { 66 | super( 67 | "Sample Alert Condition", 68 | "https://www.graylog.org/", 69 | "This is a documentation sample and never triggers." 70 | ); 71 | } 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/org/graylog/plugins/sample/alerts/SampleAlertNotification.java: -------------------------------------------------------------------------------- 1 | package org.graylog.plugins.sample.alerts; 2 | 3 | import org.graylog2.plugin.alarms.AlertCondition; 4 | import org.graylog2.plugin.alarms.callbacks.AlarmCallback; 5 | import org.graylog2.plugin.alarms.callbacks.AlarmCallbackConfigurationException; 6 | import org.graylog2.plugin.alarms.callbacks.AlarmCallbackException; 7 | import org.graylog2.plugin.configuration.Configuration; 8 | import org.graylog2.plugin.configuration.ConfigurationException; 9 | import org.graylog2.plugin.configuration.ConfigurationRequest; 10 | import org.graylog2.plugin.streams.Stream; 11 | 12 | import java.util.Map; 13 | 14 | public class SampleAlertNotification implements AlarmCallback { 15 | 16 | private Configuration config; 17 | 18 | @Override 19 | public void initialize(Configuration config) throws AlarmCallbackConfigurationException { 20 | this.config = config; 21 | } 22 | 23 | @Override 24 | public void call(Stream stream, AlertCondition.CheckResult result) throws AlarmCallbackException { 25 | 26 | } 27 | 28 | @Override 29 | public ConfigurationRequest getRequestedConfiguration() { 30 | return new ConfigurationRequest(); 31 | } 32 | 33 | @Override 34 | public String getName() { 35 | return "Sample Alert Notification"; 36 | } 37 | 38 | @Override 39 | public Map getAttributes() { 40 | return config.getSource(); 41 | } 42 | 43 | @Override 44 | public void checkConfiguration() throws ConfigurationException { 45 | 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/org/graylog/plugins/sample/decorator/SampleDecorator.java: -------------------------------------------------------------------------------- 1 | package org.graylog.plugins.sample.decorator; 2 | 3 | import com.google.inject.assistedinject.Assisted; 4 | 5 | import org.graylog2.decorators.Decorator; 6 | import org.graylog2.plugin.configuration.ConfigurationRequest; 7 | import org.graylog2.plugin.decorators.SearchResponseDecorator; 8 | import org.graylog2.rest.resources.search.responses.SearchResponse; 9 | 10 | import javax.inject.Inject; 11 | 12 | public class SampleDecorator implements SearchResponseDecorator { 13 | 14 | private Decorator decorator; 15 | 16 | @Inject 17 | public SampleDecorator(@Assisted Decorator decorator) { 18 | this.decorator = decorator; 19 | } 20 | 21 | @Override 22 | public SearchResponse apply(SearchResponse searchResponse) { 23 | return searchResponse; 24 | } 25 | 26 | public interface Factory extends SearchResponseDecorator.Factory { 27 | @Override 28 | SampleDecorator create(Decorator decorator); 29 | 30 | @Override 31 | SampleDecorator.Config getConfig(); 32 | 33 | @Override 34 | SampleDecorator.Descriptor getDescriptor(); 35 | } 36 | 37 | public static class Config implements SearchResponseDecorator.Config { 38 | 39 | @Override 40 | public ConfigurationRequest getRequestedConfiguration() { 41 | return new ConfigurationRequest(); 42 | } 43 | } 44 | 45 | public static class Descriptor extends SearchResponseDecorator.Descriptor { 46 | public Descriptor() { 47 | super("Sample decorator", "http://docs.graylog.org/", "Sample Decorator"); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/services/org.graylog2.plugin.Plugin: -------------------------------------------------------------------------------- 1 | org.graylog.plugins.sample.SamplePlugin -------------------------------------------------------------------------------- /src/main/resources/org.graylog.plugins.graylog-plugin-sample/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/web/index.jsx: -------------------------------------------------------------------------------- 1 | import packageJson from '../../package.json'; 2 | import { PluginManifest, PluginStore } from 'graylog-web-plugin/plugin'; 3 | 4 | import SamplePage from 'pages/SamplePage'; 5 | 6 | PluginStore.register(new PluginManifest(packageJson, { 7 | /* This is the place where you define which entities you are providing to the web interface. 8 | Right now you can add routes and navigation elements to it. 9 | 10 | Examples: */ 11 | 12 | // Adding a route to /sample, rendering YourReactComponent when called: 13 | 14 | routes: [ 15 | { path: '/sample', component: SamplePage }, 16 | ], 17 | 18 | // Adding an element to the top navigation pointing to /sample named "Sample": 19 | 20 | navigation: [ 21 | { path: '/sample', description: 'Sample' }, 22 | ], 23 | 24 | systemnavigation: [ 25 | { path: '/sample', description: 'Sample' }, 26 | ] 27 | })); 28 | -------------------------------------------------------------------------------- /src/web/pages/SamplePage.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import { Row, Col } from 'react-bootstrap'; 4 | 5 | import { PageHeader } from 'components/common'; 6 | 7 | const SamplePage = React.createClass({ 8 | render() { 9 | return ( 10 | 11 | 12 | Hello from the Sample plugin! 13 | 14 | 15 | ); 16 | } 17 | }); 18 | 19 | export default SamplePage; 20 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const PluginWebpackConfig = require('graylog-web-plugin').PluginWebpackConfig; 2 | const loadBuildConfig = require('graylog-web-plugin').loadBuildConfig; 3 | const path = require('path'); 4 | 5 | module.exports = new PluginWebpackConfig(path.resolve(__dirname), 'org.graylog.plugins.sample.SamplePlugin', loadBuildConfig(path.resolve(__dirname, './build.config')), { 6 | // Here goes your additional webpack configuration. 7 | }); 8 | --------------------------------------------------------------------------------