diff --git a/integrations/observability/java_client/README.md b/integrations/observability/java_client/README.md new file mode 100644 index 0000000..8e8549f --- /dev/null +++ b/integrations/observability/java_client/README.md @@ -0,0 +1,199 @@ +```markdown +# OpenSearch Java Client Documentation + +The OpenSearch Java client allows you to interact with your OpenSearch clusters through Java methods and data structures rather than HTTP methods and raw JSON. This guide illustrates how to connect to OpenSearch, index documents, and run queries. + +## Installing the Client + +### Using RestClient Transport +Add the following dependencies to your `pom.xml`: +```xml + + org.opensearch.client + opensearch-rest-client + 2.15.0 + + + org.opensearch.client + opensearch-java + 2.6.0 + +``` +For Gradle: +```gradle +dependencies { + implementation 'org.opensearch.client:opensearch-rest-client:2.15.0' + implementation 'org.opensearch.client:opensearch-java:2.6.0' +} +``` + +## Security +Configure the application's truststore to connect to the Security plugin: +```bash +keytool -import -alias -keystore +``` + +## Sample Data +Define an `IndexData` class: +```java +static class IndexData { + private String firstName; + private String lastName; + + public IndexData(String firstName, String lastName) { + this.firstName = firstName; + this.lastName = lastName; + } + + public String getFirstName() { return firstName; } + public void setFirstName(String firstName) { this.firstName = firstName; } + public String getLastName() { return lastName; } + public void setLastName(String lastName) { this.lastName = lastName; } + + @Override + public String toString() { + return String.format("IndexData{first name='%s', last name='%s'}", firstName, lastName); + } +} +``` + +## Initializing the Client with SSL and TLS + +### Using RestClient Transport +```java +import org.apache.http.HttpHost; +import org.apache.http.auth.AuthScope; +import org.apache.http.auth.UsernamePasswordCredentials; +import org.apache.http.impl.client.BasicCredentialsProvider; +import org.opensearch.client.RestClient; +import org.opensearch.client.RestClientBuilder; +import org.opensearch.client.opensearch.OpenSearchClient; +import org.opensearch.client.transport.rest_client.RestClientTransport; + +public class OpenSearchClientExample { + public static void main(String[] args) throws Exception { + System.setProperty("javax.net.ssl.trustStore", "/full/path/to/keystore"); + System.setProperty("javax.net.ssl.trustStorePassword", "password-to-keystore"); + + final HttpHost host = new HttpHost("https", "localhost", 9200); + final BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider(); + credentialsProvider.setCredentials(new AuthScope(host), new UsernamePasswordCredentials("admin", "admin".toCharArray())); + + final RestClient restClient = RestClient.builder(host).setHttpClientConfigCallback(httpClientBuilder -> { + return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider); + }).build(); + + final OpenSearchClient client = new OpenSearchClient(new RestClientTransport(restClient, new JacksonJsonpMapper())); + } +} +``` + +## Creating an Index +```java +String index = "sample-index"; +CreateIndexRequest createIndexRequest = new CreateIndexRequest.Builder().index(index).build(); +client.indices().create(createIndexRequest); + +IndexSettings indexSettings = new IndexSettings.Builder().autoExpandReplicas("0-all").build(); +PutIndicesSettingsRequest putIndicesSettingsRequest = new PutIndicesSettingsRequest.Builder().index(index).value(indexSettings).build(); +client.indices().putSettings(putIndicesSettingsRequest); +``` + +## Indexing Data +```java +IndexData indexData = new IndexData("first_name", "Bruce"); +IndexRequest indexRequest = new IndexRequest.Builder().index(index).id("1").document(indexData).build(); +client.index(indexRequest); +``` + +## Searching for Documents +```java +SearchResponse searchResponse = client.search(s -> s.index(index), IndexData.class); +for (int i = 0; i< searchResponse.hits().hits().size(); i++) { + System.out.println(searchResponse.hits().hits().get(i).source()); +} +``` + +## Best Practices for Effective Logging + +1. **Descriptive Log Messages**: Include clear and detailed information. +2. **Appropriate Log Levels**: Use different levels (INFO, DEBUG, ERROR) to categorize log messages. +3. **Timestamps**: Always include timestamps for chronological analysis. +4. **Contextual Information**: Add details like module, function, or user IDs. +5. **Avoid Redundant Logging**: Balance between sufficient information and avoiding overload. +6. **Secure Sensitive Information**: Do not log sensitive data in plain text. +7. **Structured Logging**: Use JSON for consistent log formats. + +## Advanced Features of OpenSearch + +- **Index Patterns and Mappings**: Optimize log data structure for better analysis and retrieval. +- **Visualization with Dashboards**: Create interactive dashboards for real-time log insights. + +# How to build an Application Monitor Dashboard + +Based on the ingested logs, let's review the process of generating an informative monitor dashboard for the application logs: + +## Step-by-Step Tutorial: Creating an OpenSearch Dashboard for Application Logs + +### 1. Log in to OpenSearch Dashboards + +- Navigate to OpenSearch Dashboards. +- Log in and verify the logs index was created and contains logs data. +- Go to the Discover tab, select the index name, and view the data. + +### 2. Create an Index Pattern + +- Go to 'Management' > 'Index Patterns'. +- Click 'Create Index Pattern' and enter the pattern (e.g., logs-*). +- Select the timestamp field (e.g., @timestamp) for time-based data. +- Save the index pattern. + +### 3. Build Log Queries + +- Go to the 'Discover' tab. +- Use the search bar to filter logs, e.g., `log_level:ERROR` to find all error logs. +- For advanced filtering, utilize the Dashboard Query Language (DQL). + +### 4. Save Your Query + +- After refining your query, save it by clicking on the 'Save' button in the 'Discover' tab. +- Name your saved query for easy reference. + +### 5. Create Visualizations + +- Go to 'Visualize' > 'Create Visualization'. +- Select the type of visualization you want to create (e.g., bar chart, pie chart). +- Choose your saved query as the data source. + +### 6. Add Buckets for Data Aggregation + +- In the visualization settings, add buckets to aggregate your data. For example: + - Use 'Date Histogram' for the X-axis to display logs over time. + - Add other metrics or aggregations as needed. + +### 7. Split Series for Detailed Insights + +- Add another bucket to split data by specific fields, such as `service.name` or `host.name`. +- This will allow you to see log distributions across different services or hosts. + +### 8. Customize Visualization + +- Customize the visualization with labels, colors, and other settings to make it more informative and visually appealing. + +### 9. Save and Add to Dashboard + +- Save the visualization with a descriptive name. +- Navigate to the 'Dashboard' tab and create a new dashboard. +- Add your saved visualizations to the dashboard by selecting them from the list. + +### 10. Finalize and Share + +- Arrange the visualizations on the dashboard as desired. +- Save the dashboard with a meaningful name. +- Share the dashboard with your team by generating a shareable link or embedding it in your application. + +### Tips for Effective Dashboards + +- Use different types of visualizations to present various aspects of your log data. +- Regularly update the time filter to ensure you're viewing the most recent logs. +- Take advantage of OpenSearch Dashboards' interactive features, such as drill-downs and filters, for deeper analysis. \ No newline at end of file diff --git a/integrations/observability/java_client/assets/tutorial-1.0.0.ndjson b/integrations/observability/java_client/assets/tutorial-1.0.0.ndjson new file mode 100644 index 0000000..db3e06e --- /dev/null +++ b/integrations/observability/java_client/assets/tutorial-1.0.0.ndjson @@ -0,0 +1,4 @@ +{"attributes":{"description":"Getting started for java client instructions v","kibanaSavedObjectMeta":{"searchSourceJSON":"{\"query\":{\"query\":\"\",\"language\":\"kuery\"},\"filter\":[]}"},"title":"java_client","uiStateJSON":"{}","version":1,"visState":"{\"title\":\"java_client\",\"type\":\"markdown\",\"aggs\":[],\"params\":{\"fontSize\":12,\"openLinksInNewTab\":false,\"markdown\":\"Here's a similar getting started guide for Java based on the provided Python instructions.\\n\\n# Java Client Integration\\n\\nThis guide provides instructions and a tutorial on setting up the Java OpenSearch client and logging application telemetry into OpenSearch.\\n\\n## Logging with OpenSearch in Java:\\n\\nLogging is an important aspect of software development, and OpenSearch is a robust and scalable solution for storing and analyzing logs efficiently. This guide walks you through integrating OpenSearch as a storage and analytics component in your Java project for effective logging.\\n\\n### Install Java Libraries\\n\\nAdd the OpenSearch Java client to your Maven project's `pom.xml` to interact with OpenSearch:\\n\\n```xml\\n\\n org.opensearch.client\\n opensearch-rest-client\\n 2.15.0\\n\\n\\n\\n org.opensearch.client\\n opensearch-java\\n 2.6.0\\n\\n```\\nSee additional documentation [here](https://opensearch.org/docs/latest/clients/java/).\\n\\n## Integrating OpenSearch with Your Java Project\\n\\n### Step 1: Import the OpenSearch Client\\n\\nIn your Java project, use a class called IndexData, which is a simple Java class that stores basic data and methods.\\nFor your own OpenSearch cluster, you might find that you need a more robust class to store your data.\\n\\n\\n\\n```java\\nstatic class IndexData {\\n private String firstName;\\n private String lastName;\\n\\n public IndexData(String firstName, String lastName) {\\n this.firstName = firstName;\\n this.lastName = lastName;\\n }\\n\\n public String getFirstName() {\\n return firstName;\\n }\\n\\n public void setFirstName(String firstName) {\\n this.firstName = firstName;\\n }\\n\\n public String getLastName() {\\n return lastName;\\n }\\n\\n public void setLastName(String lastName) {\\n this.lastName = lastName;\\n }\\n\\n @Override\\n public String toString() {\\n return String.format(\\\"IndexData{first name='%s', last name='%s'}\\\", firstName, lastName);\\n }\\n}\\n```\\n\\n### Step 2: Establish a Connection\\n\\nInitializing the client with SSL and TLS enabled using RestClient Transport\\nThis code example uses basic credentials that come with the default OpenSearch configuration.\\nIf you’re using the Java client with your own OpenSearch cluster, be sure to change the code so that it uses your own credentials.\\n\\n\\n```java\\nimport org.apache.http.HttpHost;\\nimport org.apache.http.auth.AuthScope;\\nimport org.apache.http.auth.UsernamePasswordCredentials;\\nimport org.apache.http.impl.nio.client.HttpAsyncClientBuilder;\\nimport org.apache.http.impl.client.BasicCredentialsProvider;\\nimport org.opensearch.client.RestClient;\\nimport org.opensearch.client.RestClientBuilder;\\nimport org.opensearch.client.json.jackson.JacksonJsonpMapper;\\nimport org.opensearch.client.opensearch.OpenSearchClient;\\nimport org.opensearch.client.transport.OpenSearchTransport;\\nimport org.opensearch.client.transport.rest_client.RestClientTransport;\\n\\npublic class OpenSearchClientExample {\\n public static void main(String[] args) throws Exception {\\n System.setProperty(\\\"javax.net.ssl.trustStore\\\", \\\"/full/path/to/keystore\\\");\\n System.setProperty(\\\"javax.net.ssl.trustStorePassword\\\", \\\"password-to-keystore\\\");\\n\\n final HttpHost host = new HttpHost(\\\"https\\\", \\\"localhost\\\", 9200);\\n final BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();\\n //Only for demo purposes. Don't specify your credentials in code.\\n credentialsProvider.setCredentials(new AuthScope(host), new UsernamePasswordCredentials(\\\"admin\\\", \\\"admin\\\".toCharArray()));\\n\\n //Initialize the client with SSL and TLS enabled\\n final RestClient restClient = RestClient.builder(host).\\n setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {\\n @Override\\n public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {\\n return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);\\n }\\n }).build();\\n\\n final OpenSearchTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper());\\n final OpenSearchClient client = new OpenSearchClient(transport);\\n }\\n}\\n```\\n\\n### Step 3: Indexing Logs\\nYou can create an index with non-default settings using the following code:\\n```java\\nString index = \\\"sample-index\\\";\\n CreateIndexRequest createIndexRequest = new CreateIndexRequest.Builder().index(index).build();\\n client.indices().create(createIndexRequest);\\n\\n IndexSettings indexSettings = new IndexSettings.Builder().autoExpandReplicas(\\\"0-all\\\").build();\\n PutIndicesSettingsRequest putIndicesSettingsRequest = new PutIndicesSettingsRequest.Builder().index(index).value(indexSettings).build();\\n client.indices().putSettings(putIndicesSettingsRequest);\\n```\\n\\nIndex your logs into OpenSearch:\\n\\n```java\\nIndexData indexData = new IndexData(\\\"first_name\\\", \\\"Bruce\\\");\\nIndexRequest indexRequest = new IndexRequest.Builder().index(index).id(\\\"1\\\").document(indexData).build();\\nclient.index(indexRequest);\\n```\\n\\n### Step 4: Querying Logs\\n\\nRetrieve logs using OpenSearch's powerful search capabilities:\\n\\n```java\\nSearchResponse searchResponse = client.search(s -> s.index(index), IndexData.class);\\nfor (int i = 0; i< searchResponse.hits().hits().size(); i++) {\\n System.out.println(searchResponse.hits().hits().get(i).source());\\n }\\n```\\n\\n## Best Practices for Effective Logging\\n\\n1. **Descriptive Log Messages**: Include clear and detailed information.\\n2. **Appropriate Log Levels**: Use different levels (INFO, DEBUG, ERROR) to categorize log messages.\\n3. **Timestamps**: Always include timestamps for chronological analysis.\\n4. **Contextual Information**: Add details like module, function, or user IDs.\\n5. **Avoid Redundant Logging**: Balance between sufficient information and avoiding overload.\\n6. **Secure Sensitive Information**: Do not log sensitive data in plain text.\\n7. **Structured Logging**: Use JSON for consistent log formats.\\n\\n## Advanced Features of OpenSearch\\n\\n- **Index Patterns and Mappings**: Optimize log data structure for better analysis and retrieval.\\n- **Visualization with Dashboards**: Create interactive dashboards for real-time log insights.\\n\\n# How to build an Application Monitor Dashboard\\n\\nBased on the ingested logs, let's review the process of generating an informative monitor dashboard for the application logs:\\n\\n## Step-by-Step Tutorial: Creating an OpenSearch Dashboard for Application Logs\\n\\n### 1. Log in to OpenSearch Dashboards\\n\\n- Navigate to OpenSearch Dashboards.\\n- Log in and verify the logs index was created and contains logs data.\\n- Go to the Discover tab, select the index name, and view the data.\\n\\n### 2. Create an Index Pattern\\n\\n- Go to 'Management' > 'Index Patterns'.\\n- Click 'Create Index Pattern' and enter the pattern (e.g., logs-*).\\n- Select the timestamp field (e.g., @timestamp) for time-based data.\\n- Save the index pattern.\\n\\n### 3. Build Log Queries\\n\\n- Go to the 'Discover' tab.\\n- Use the search bar to filter logs, e.g., `log_level:ERROR` to find all error logs.\\n- For advanced filtering, utilize the Dashboard Query Language (DQL).\\n\\n### 4. Save Your Query\\n\\n- After refining your query, save it by clicking on the 'Save' button in the 'Discover' tab.\\n- Name your saved query for easy reference.\\n\\n### 5. Create Visualizations\\n\\n- Go to 'Visualize' > 'Create Visualization'.\\n- Select the type of visualization you want to create (e.g., bar chart, pie chart).\\n- Choose your saved query as the data source.\\n\\n### 6. Add Buckets for Data Aggregation\\n\\n- In the visualization settings, add buckets to aggregate your data. For example:\\n - Use 'Date Histogram' for the X-axis to display logs over time.\\n - Add other metrics or aggregations as needed.\\n\\n### 7. Split Series for Detailed Insights\\n\\n- Add another bucket to split data by specific fields, such as `service.name` or `host.name`.\\n- This will allow you to see log distributions across different services or hosts.\\n\\n### 8. Customize Visualization\\n\\n- Customize the visualization with labels, colors, and other settings to make it more informative and visually appealing.\\n\\n### 9. Save and Add to Dashboard\\n\\n- Save the visualization with a descriptive name.\\n- Navigate to the 'Dashboard' tab and create a new dashboard.\\n- Add your saved visualizations to the dashboard by selecting them from the list.\\n\\n### 10. Finalize and Share\\n\\n- Arrange the visualizations on the dashboard as desired.\\n- Save the dashboard with a meaningful name.\\n- Share the dashboard with your team by generating a shareable link or embedding it in your application.\\n\\n### Tips for Effective Dashboards\\n\\n- Use different types of visualizations to present various aspects of your log data.\\n- Regularly update the time filter to ensure you're viewing the most recent logs.\\n- Take advantage of OpenSearch Dashboards' interactive features, such as drill-downs and filters, for deeper analysis.\"}}"},"id":"128d0790-47e5-11ef-89c9-a5eb94f3bbbc","migrationVersion":{"visualization":"7.10.0"},"references":[],"type":"visualization","updated_at":"2024-07-22T04:44:25.609Z","version":"WzcyLDdd"} +{"attributes":{"description":"getting started instructions for a java client based applicative logs dashboard","hits":0,"kibanaSavedObjectMeta":{"searchSourceJSON":"{\"query\":{\"language\":\"kuery\",\"query\":\"\"},\"filter\":[]}"},"optionsJSON":"{\"hidePanelTitles\":false,\"useMargins\":true}","panelsJSON":"[{\"version\":\"2.15.0\",\"gridData\":{\"x\":0,\"y\":0,\"w\":24,\"h\":15,\"i\":\"39184cd8-b84d-48c8-821d-f749007e8bd0\"},\"panelIndex\":\"39184cd8-b84d-48c8-821d-f749007e8bd0\",\"embeddableConfig\":{},\"panelRefName\":\"panel_0\"}]","timeRestore":false,"title":"java_client-dashboard","version":1},"id":"java_client_getting-started-dashboard","migrationVersion":{"dashboard":"7.9.3"},"references":[{"id":"128d0790-47e5-11ef-89c9-a5eb94f3bbbc","name":"panel_0","type":"visualization"}],"type":"dashboard","updated_at":"2024-07-22T04:44:54.511Z","version":"WzczLDdd"} +{"attributes":{"fields":"[{\"count\":0,\"name\":\"_id\",\"type\":\"string\",\"esTypes\":[\"_id\"],\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":false},{\"count\":0,\"name\":\"_index\",\"type\":\"string\",\"esTypes\":[\"_index\"],\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":false},{\"count\":0,\"name\":\"_score\",\"type\":\"number\",\"scripted\":false,\"searchable\":false,\"aggregatable\":false,\"readFromDocValues\":false},{\"count\":0,\"name\":\"_source\",\"type\":\"_source\",\"esTypes\":[\"_source\"],\"scripted\":false,\"searchable\":false,\"aggregatable\":false,\"readFromDocValues\":false},{\"count\":0,\"name\":\"_type\",\"type\":\"string\",\"scripted\":false,\"searchable\":false,\"aggregatable\":false,\"readFromDocValues\":false},{\"count\":0,\"name\":\"error_code\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"count\":0,\"name\":\"function\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"count\":0,\"name\":\"level\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"count\":0,\"name\":\"message\",\"type\":\"string\",\"esTypes\":[\"text\"],\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"count\":0,\"name\":\"module\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"count\":0,\"name\":\"source\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"count\":0,\"name\":\"timestamp\",\"type\":\"date\",\"esTypes\":[\"date\"],\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"count\":0,\"name\":\"user_id\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true}]","timeFieldName":"timestamp","title":"applicative_logs*"},"id":"15746330-447b-11ef-99f2-2b48f7e65060","migrationVersion":{"index-pattern":"7.6.0"},"references":[],"type":"index-pattern","updated_at":"2024-07-19T21:03:51.880Z","version":"WzIxLDJd"} +{"exportedCount":3,"missingRefCount":0,"missingReferences":[]} \ No newline at end of file diff --git a/integrations/observability/java_client/data/sample.json b/integrations/observability/java_client/data/sample.json new file mode 100644 index 0000000..2671788 --- /dev/null +++ b/integrations/observability/java_client/data/sample.json @@ -0,0 +1,52 @@ +[ + { + "timestamp": "2024-02-05T12:00:00", + "level": "info", + "message": "Application started successfully.", + "source": "your_python_project", + "module": "main", + "function": "start_app" + }, + { + "timestamp": "2024-02-05T12:01:00", + "level": "debug", + "message": "Connecting to database.", + "source": "your_python_project", + "module": "database", + "function": "connect" + }, + { + "timestamp": "2024-02-05T12:02:00", + "level": "error", + "message": "Database connection failed.", + "source": "your_python_project", + "module": "database", + "function": "connect", + "error_code": "DB_CONN_FAIL" + }, + { + "timestamp": "2024-02-05T12:03:00", + "level": "info", + "message": "Retrying database connection.", + "source": "your_python_project", + "module": "database", + "function": "connect" + }, + { + "timestamp": "2024-02-05T12:04:00", + "level": "info", + "message": "Database connection established.", + "source": "your_python_project", + "module": "database", + "function": "connect" + }, + { + "timestamp": "2024-02-05T12:05:00", + "level": "info", + "message": "Processing user request.", + "source": "your_python_project", + "module": "request_handler", + "function": "process_request", + "user_id": "user_123" + } +] diff --git a/integrations/observability/java_client/getting-started/.env b/integrations/observability/java_client/getting-started/.env new file mode 100644 index 0000000..1788fdf --- /dev/null +++ b/integrations/observability/java_client/getting-started/.env @@ -0,0 +1,14 @@ +# OpenSearch version +OPENSEARCH_VERSION=2.15.0 +OPENSEARCH_ADMIN_PASSWORD=my_%New%_passW0rd!@# +OPENSEARCH_INITIAL_ADMIN_PASSWORD=my_%New%_passW0rd!@# + +# OpenSearch Node1 +OPENSEARCH_PORT=9200 +OPENSEARCH_HOST=opensearch +OPENSEARCH_ADDR=${OPENSEARCH_HOST}:${OPENSEARCH_PORT} + +# OpenSearch Dashboard +OPENSEARCH_DASHBOARD_PORT=5601 +OPENSEARCH_DASHBOARD_HOST=opensearch-dashboards +OPENSEARCH_DASHBOARD_ADDR=${OPENSEARCH_DASHBOARD_HOST}:${OPENSEARCH_DASHBOARD_PORT} diff --git a/integrations/observability/java_client/getting-started/Getting-Started.md b/integrations/observability/java_client/getting-started/Getting-Started.md new file mode 100644 index 0000000..c29901b --- /dev/null +++ b/integrations/observability/java_client/getting-started/Getting-Started.md @@ -0,0 +1,230 @@ +Here's a similar getting started guide for Java based on the provided Python instructions. + +# Java Client Integration + +This guide provides instructions and a tutorial on setting up the Java OpenSearch client and logging application telemetry into OpenSearch. + +## Logging with OpenSearch in Java: + +Logging is an important aspect of software development, and OpenSearch is a robust and scalable solution for storing and analyzing logs efficiently. This guide walks you through integrating OpenSearch as a storage and analytics component in your Java project for effective logging. + +### Install Java Libraries + +Add the OpenSearch Java client to your Maven project's `pom.xml` to interact with OpenSearch: + +```xml + + org.opensearch.client + opensearch-rest-client + 2.15.0 + + + + org.opensearch.client + opensearch-java + 2.6.0 + +``` +See additional documentation [here](https://opensearch.org/docs/latest/clients/java/). + +## Integrating OpenSearch with Your Java Project + +### Step 1: Import the OpenSearch Client + +In your Java project, use a class called IndexData, which is a simple Java class that stores basic data and methods. +For your own OpenSearch cluster, you might find that you need a more robust class to store your data. + + + +```java +static class IndexData { + private String firstName; + private String lastName; + + public IndexData(String firstName, String lastName) { + this.firstName = firstName; + this.lastName = lastName; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + @Override + public String toString() { + return String.format("IndexData{first name='%s', last name='%s'}", firstName, lastName); + } +} +``` + +### Step 2: Establish a Connection + +Initializing the client with SSL and TLS enabled using RestClient Transport +This code example uses basic credentials that come with the default OpenSearch configuration. +If you’re using the Java client with your own OpenSearch cluster, be sure to change the code so that it uses your own credentials. + + +```java +import org.apache.http.HttpHost; +import org.apache.http.auth.AuthScope; +import org.apache.http.auth.UsernamePasswordCredentials; +import org.apache.http.impl.nio.client.HttpAsyncClientBuilder; +import org.apache.http.impl.client.BasicCredentialsProvider; +import org.opensearch.client.RestClient; +import org.opensearch.client.RestClientBuilder; +import org.opensearch.client.json.jackson.JacksonJsonpMapper; +import org.opensearch.client.opensearch.OpenSearchClient; +import org.opensearch.client.transport.OpenSearchTransport; +import org.opensearch.client.transport.rest_client.RestClientTransport; + +public class OpenSearchClientExample { + public static void main(String[] args) throws Exception { + System.setProperty("javax.net.ssl.trustStore", "/full/path/to/keystore"); + System.setProperty("javax.net.ssl.trustStorePassword", "password-to-keystore"); + + final HttpHost host = new HttpHost("https", "localhost", 9200); + final BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider(); + //Only for demo purposes. Don't specify your credentials in code. + credentialsProvider.setCredentials(new AuthScope(host), new UsernamePasswordCredentials("admin", "admin".toCharArray())); + + //Initialize the client with SSL and TLS enabled + final RestClient restClient = RestClient.builder(host). + setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() { + @Override + public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) { + return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider); + } + }).build(); + + final OpenSearchTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper()); + final OpenSearchClient client = new OpenSearchClient(transport); + } +} +``` + +### Step 3: Indexing Logs +You can create an index with non-default settings using the following code: +```java +String index = "sample-index"; + CreateIndexRequest createIndexRequest = new CreateIndexRequest.Builder().index(index).build(); + client.indices().create(createIndexRequest); + + IndexSettings indexSettings = new IndexSettings.Builder().autoExpandReplicas("0-all").build(); + PutIndicesSettingsRequest putIndicesSettingsRequest = new PutIndicesSettingsRequest.Builder().index(index).value(indexSettings).build(); + client.indices().putSettings(putIndicesSettingsRequest); +``` + +Index your logs into OpenSearch: + +```java +IndexData indexData = new IndexData("first_name", "Bruce"); +IndexRequest indexRequest = new IndexRequest.Builder().index(index).id("1").document(indexData).build(); +client.index(indexRequest); +``` + +### Step 4: Querying Logs + +Retrieve logs using OpenSearch's powerful search capabilities: + +```java +SearchResponse searchResponse = client.search(s -> s.index(index), IndexData.class); +for (int i = 0; i< searchResponse.hits().hits().size(); i++) { + System.out.println(searchResponse.hits().hits().get(i).source()); + } +``` + +## Best Practices for Effective Logging + +1. **Descriptive Log Messages**: Include clear and detailed information. +2. **Appropriate Log Levels**: Use different levels (INFO, DEBUG, ERROR) to categorize log messages. +3. **Timestamps**: Always include timestamps for chronological analysis. +4. **Contextual Information**: Add details like module, function, or user IDs. +5. **Avoid Redundant Logging**: Balance between sufficient information and avoiding overload. +6. **Secure Sensitive Information**: Do not log sensitive data in plain text. +7. **Structured Logging**: Use JSON for consistent log formats. + +## Advanced Features of OpenSearch + +- **Index Patterns and Mappings**: Optimize log data structure for better analysis and retrieval. +- **Visualization with Dashboards**: Create interactive dashboards for real-time log insights. + +# How to build an Application Monitor Dashboard + +Based on the ingested logs, let's review the process of generating an informative monitor dashboard for the application logs: + +## Step-by-Step Tutorial: Creating an OpenSearch Dashboard for Application Logs + +### 1. Log in to OpenSearch Dashboards + +- Navigate to OpenSearch Dashboards. +- Log in and verify the logs index was created and contains logs data. +- Go to the Discover tab, select the index name, and view the data. + +### 2. Create an Index Pattern + +- Go to 'Management' > 'Index Patterns'. +- Click 'Create Index Pattern' and enter the pattern (e.g., logs-*). +- Select the timestamp field (e.g., @timestamp) for time-based data. +- Save the index pattern. + +### 3. Build Log Queries + +- Go to the 'Discover' tab. +- Use the search bar to filter logs, e.g., `log_level:ERROR` to find all error logs. +- For advanced filtering, utilize the Dashboard Query Language (DQL). + +### 4. Save Your Query + +- After refining your query, save it by clicking on the 'Save' button in the 'Discover' tab. +- Name your saved query for easy reference. + +### 5. Create Visualizations + +- Go to 'Visualize' > 'Create Visualization'. +- Select the type of visualization you want to create (e.g., bar chart, pie chart). +- Choose your saved query as the data source. + +### 6. Add Buckets for Data Aggregation + +- In the visualization settings, add buckets to aggregate your data. For example: + - Use 'Date Histogram' for the X-axis to display logs over time. + - Add other metrics or aggregations as needed. + +### 7. Split Series for Detailed Insights + +- Add another bucket to split data by specific fields, such as `service.name` or `host.name`. +- This will allow you to see log distributions across different services or hosts. + +### 8. Customize Visualization + +- Customize the visualization with labels, colors, and other settings to make it more informative and visually appealing. + +### 9. Save and Add to Dashboard + +- Save the visualization with a descriptive name. +- Navigate to the 'Dashboard' tab and create a new dashboard. +- Add your saved visualizations to the dashboard by selecting them from the list. + +### 10. Finalize and Share + +- Arrange the visualizations on the dashboard as desired. +- Save the dashboard with a meaningful name. +- Share the dashboard with your team by generating a shareable link or embedding it in your application. + +### Tips for Effective Dashboards + +- Use different types of visualizations to present various aspects of your log data. +- Regularly update the time filter to ensure you're viewing the most recent logs. +- Take advantage of OpenSearch Dashboards' interactive features, such as drill-downs and filters, for deeper analysis. \ No newline at end of file diff --git a/integrations/observability/java_client/getting-started/data/sample.json b/integrations/observability/java_client/getting-started/data/sample.json new file mode 100644 index 0000000..2671788 --- /dev/null +++ b/integrations/observability/java_client/getting-started/data/sample.json @@ -0,0 +1,52 @@ +[ + { + "timestamp": "2024-02-05T12:00:00", + "level": "info", + "message": "Application started successfully.", + "source": "your_python_project", + "module": "main", + "function": "start_app" + }, + { + "timestamp": "2024-02-05T12:01:00", + "level": "debug", + "message": "Connecting to database.", + "source": "your_python_project", + "module": "database", + "function": "connect" + }, + { + "timestamp": "2024-02-05T12:02:00", + "level": "error", + "message": "Database connection failed.", + "source": "your_python_project", + "module": "database", + "function": "connect", + "error_code": "DB_CONN_FAIL" + }, + { + "timestamp": "2024-02-05T12:03:00", + "level": "info", + "message": "Retrying database connection.", + "source": "your_python_project", + "module": "database", + "function": "connect" + }, + { + "timestamp": "2024-02-05T12:04:00", + "level": "info", + "message": "Database connection established.", + "source": "your_python_project", + "module": "database", + "function": "connect" + }, + { + "timestamp": "2024-02-05T12:05:00", + "level": "info", + "message": "Processing user request.", + "source": "your_python_project", + "module": "request_handler", + "function": "process_request", + "user_id": "user_123" + } +] diff --git a/integrations/observability/java_client/getting-started/docker-compose.yml b/integrations/observability/java_client/getting-started/docker-compose.yml new file mode 100644 index 0000000..7af0b95 --- /dev/null +++ b/integrations/observability/java_client/getting-started/docker-compose.yml @@ -0,0 +1,67 @@ +version: '3.8' + +services: + java-app: + build: ./java-app + volumes: + - ./logs:/logs + restart: always + + fluent-bit: + container_name: fluent-bit + image: fluent/fluent-bit:latest + volumes: + - ./logs:/logs + - ./fluent-bit:/fluent-bit/etc + ports: + - "24224:24224" + - "24224:24224/udp" + networks: + - opensearch-net + + opensearch-dashboards: + image: opensearchproject/opensearch-dashboards:${OPENSEARCH_VERSION} + container_name: opensearch-dashboards + ports: + - 5601:5601 + expose: + - "5601" + environment: + OPENSEARCH_HOSTS: '["https://opensearch-node1:9200"]' + depends_on: + - opensearch-node1 + volumes: + - ./opensearch_dashboards.yml:/usr/share/opensearch-dashboards/config/opensearch_dashboards.yml + networks: + - opensearch-net + + opensearch-node1: + image: opensearchproject/opensearch:${OPENSEARCH_VERSION} + container_name: opensearch-node1 + environment: + - cluster.name=my-cluster + - node.name=opensearch-node1 + - discovery.seed_hosts=opensearch-node1 + - cluster.initial_master_nodes=opensearch-node1 + - bootstrap.memory_lock=true + - plugins.query.datasources.encryption.masterkey=8e3f206ea7c07cc1bfc5cf40 + - "OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m" + - "OPENSEARCH_INITIAL_ADMIN_PASSWORD=${OPENSEARCH_ADMIN_PASSWORD}" + ulimits: + memlock: + soft: -1 + hard: -1 + volumes: + - opensearch-data1:/usr/share/opensearch/data + ports: + - 9200:9200 + - 9600:9600 + networks: + - opensearch-net + +volumes: + opensearch-data1: + +networks: + opensearch-net: + external: true \ No newline at end of file diff --git a/integrations/observability/java_client/getting-started/fluent-bit/fluent-bit.conf b/integrations/observability/java_client/getting-started/fluent-bit/fluent-bit.conf new file mode 100644 index 0000000..a08b404 --- /dev/null +++ b/integrations/observability/java_client/getting-started/fluent-bit/fluent-bit.conf @@ -0,0 +1,23 @@ +[SERVICE] + Flush 1 + Log_Level info + Parsers_File parsers.conf + +[INPUT] + Name tail + Path /logs/*.log + Parser json + Tag app.log + +[OUTPUT] + Name opensearch + Host opensearch-node1 + Match * + Port 9200 + Type _doc + Index applicative_logs + tls On + tls.verify Off + Suppress_Type_Name On + HTTP_User admin + HTTP_Passwd my_%New%_passW0rd!@# diff --git a/integrations/observability/java_client/getting-started/fluent-bit/parsers.conf b/integrations/observability/java_client/getting-started/fluent-bit/parsers.conf new file mode 100644 index 0000000..2a0a87b --- /dev/null +++ b/integrations/observability/java_client/getting-started/fluent-bit/parsers.conf @@ -0,0 +1,5 @@ +[PARSER] + Name json + Format json + Time_Key time + Time_Format %d/%b/%Y:%H:%M:%S %z diff --git a/integrations/observability/java_client/getting-started/getting-started-java_client-1.0.0.json b/integrations/observability/java_client/getting-started/getting-started-java_client-1.0.0.json new file mode 100644 index 0000000..361ec14 --- /dev/null +++ b/integrations/observability/java_client/getting-started/getting-started-java_client-1.0.0.json @@ -0,0 +1,211 @@ +{ + "name": "java-client", + "version": "1.0.0", + "displayName": "java client", + "description": "java applicative logs", + "license": "Apache-2.0", + "type": "logs", + "labels": ["Observability", "Logs", "java"], + "author": "OpenSearch", + "sourceUrl": "https://github.com/opensearch-project/opensearch-catalog/tree/main/integrations/observability/java_client/getting-started", + "workflows": [ + { + "name": "dashboards", + "label": "Dashboards & Visualizations", + "description": "Dashboards and indices that enable you to easily visualize important metrics.", + "enabled_by_default": false + } + ], + "statics": { + "logo": { + "annotation": "java Logo", + "path": "logo.svg" + }, + "gallery": [ + { + "annotation": "java Client Tutorial Dashboard", + "path": "dashboard.png", + "tags": ["dashboard","getting-started"], + "savedObject-id": "java_client_getting-started-dashboard" + } + ] + }, + "assets": [ + { "name": "tutorial", "version": "1.0.0", "extension": "ndjson", "type": "savedObjectBundle", "workflows": ["dashboards"] } + ], + "getting-started": { + "ingestion": ["java-client"], + "structured": "false", + "technology": "java", + "protocol": [], + "live-sample": "true", + "workflows": [ + { + "name": "Quick Start", + "description": "This is a java-client fluent-bit based docker quick starting instructions tutorial with a live example", + "steps": [ + { + "name": "Create docker-network", + "label": "Environment setting", + "phase": "docker", + "type": "console-cmd", + "content": "docker network create opensearch-net", + "description": "Before running any docker-compose files, create the opensearch-net network" + }, + { + "name": "Setup docker .env file", + "label": "Environment Parameters", + "phase": "docker", + "type": "file-url", + "input-params": [ + { + "name": "OPENSEARCH_HOST", + "description": "Opensearch host", + "type": "host-name" + }, + { + "name": "OPENSEARCH_DASHBOARD_HOST", + "description": "Opensearch Dashboard host", + "type": "host-name" + } + ], + "info": ["https://github.com/opensearch-project/opensearch-catalog/tree/main/integrations/observability/java_client/getting-started/.env"], + "content": "wget https://raw.githubusercontent.com/opensearch-project/opensearch-catalog/tree/main/integrations/observability/java_client/getting-started/.env", + "description": "Setup docker-compose env variables " + }, + { + "name": "Setup fluent-bit folder", + "label": "Environment Parameters", + "phase": "docker", + "type": "file-url", + "info": ["https://github.com/opensearch-project/opensearch-catalog/tree/main/integrations/observability/java_client/getting-started/fluent-bit/fluent-bit.conf", + "https://github.com/opensearch-project/opensearch-catalog/tree/main/integrations/observability/java_client/getting-started/fluent-bit/parsers.conf" + ], + "content": "wget https://raw.githubusercontent.com/opensearch-project/opensearch-catalog/main/integrations/observability/java_client/getting-started/fluent-bit/fluent-bit.conf \\\n https://raw.githubusercontent.com/opensearch-project/opensearch-catalog/main/integrations/observability/java_client/getting-started/fluent-bit/parsers.conf\n", + "description": "Setup docker-compose fluent-bit's service configuration " + }, + { + "name": "Setup java app folder", + "label": "Environment Parameters", + "phase": "docker", + "type": "file-url", + "info": ["https://github.com/opensearch-project/opensearch-catalog/tree/main/integrations/observability/java_client/getting-started/java-app/Dockerfile", + "https://github.com/opensearch-project/opensearch-catalog/tree/main/integrations/observability/java_client/getting-started/java-app/src/main/java/App.java", + "https://github.com/opensearch-project/opensearch-catalog/tree/main/integrations/observability/java_client/getting-started/java-app/pom.xml" + ], + "content": "wget https://github.com/opensearch-project/opensearch-catalog/tree/main/integrations/observability/java_client/getting-started/java-app/Dockerfile \\\n https://github.com/opensearch-project/opensearch-catalog/tree/main/integrations/observability/java_client/getting-started/java-app/pom.xml \\\n https://github.com/opensearch-project/opensearch-catalog/tree/main/integrations/observability/java_client/getting-started/java-app/src/main/java/App.java \n", + "description": "Setup docker-compose java-app service configuration " + }, + { + "name": "Run docker-compose", + "label": "live container", + "type": "file-url", + "phase": "docker", + "info": ["https://github.com/opensearch-project/opensearch-catalog/tree/main/integrations/observability/java_client/getting-started/docker-compose.yml"], + "description": "Run docker-compose for the java-client live example and see the generated index", + "content": "wget -O docker-compose.yml https://raw.githubusercontent.com/opensearch-project/opensearch-catalog/main/integrations/observability/java_client/getting-started/docker-compose.yml && docker-compose up --build \n" + } + ] + }, + { + "name": "java-client", + "description": "This is a fluent-bit based getting started instructions tutorial", + "steps": [ + { + "name": "Import OpenSearch Java Client", + "type": "code", + "phase": "setup", + "label": "Client Import", + "description": "Import the OpenSearch module from the opensearchpy package", + "content": "from opensearchpy import OpenSearch" + }, + { + "name": "Create Connection to OpenSearch", + "type": "code", + "phase": "setup", + "label": "Connection Establishment", + "description": "Establish a connection to your OpenSearch cluster by creating an instance of the OpenSearch class. Provide the necessary connection details, such as the host and port.", + "input-params": [ + { + "name": "opensearch_host", + "description": "Hostname or IP address of your OpenSearch server", + "type": "host-name", + "default": "localhost" + }, + { + "name": "opensearch_port", + "description": "Port of your OpenSearch server (default is 9200)", + "type": "port", + "default": 9200 + } + ], + "content": "System.setProperty(\"javax.net.ssl.trustStore\", \"/full/path/to/keystore\");\n System.setProperty(\"javax.net.ssl.trustStorePassword\", \"password-to-keystore\");\n\n final HttpHost host = new HttpHost(\"https\", \"localhost\", 9200);\n final BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();\n credentialsProvider.setCredentials(new AuthScope(host), new UsernamePasswordCredentials(\"admin\", \"admin\".toCharArray()));\n\n final RestClient restClient = RestClient.builder(host).setHttpClientConfigCallback(httpClientBuilder -> {\n return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);\n }).build();\n\n final OpenSearchClient client = new OpenSearchClient(new RestClientTransport(restClient, new JacksonJsonpMapper()));\n" + }, + { + "name": "Indexing Logs", + "type": "code", + "phase": "logging", + "label": "Log Indexing", + "description": "Start indexing logs into OpenSearch. Indexing involves adding documents representing your log entries to OpenSearch.", + "input-params": [ + { + "name": "index_name", + "description": "Desired index name in OpenSearch", + "type": "index-name" + }, + { + "name": "timestamp", + "description": "Timestamp of the log entry", + "type": "timestamp" + }, + { + "name": "level", + "description": "Log level (e.g., info, error)", + "type": "log-level" + }, + { + "name": "message", + "description": "Log message", + "type": "log-message" + }, + { + "name": "source", + "description": "Source of the log entry", + "type": "source" + } + ], + "content": "String index = \"sample-index\";\nCreateIndexRequest createIndexRequest = new CreateIndexRequest.Builder().index(index).build();\nclient.indices().create(createIndexRequest);\n\nIndexSettings indexSettings = new IndexSettings.Builder().autoExpandReplicas(\"0-all\").build();\nPutIndicesSettingsRequest putIndicesSettingsRequest = new PutIndicesSettingsRequest.Builder().index(index).value(indexSettings).build();\nclient.indices().putSettings(putIndicesSettingsRequest);" + } + ] + } + ] + }, + "schema": [ + { + "type": "logs", + "info": [ + "https://opensearch.org/docs/latest/im-plugin/index-templates" + ], + "content": "PUT _index_template/application_logs_template", + "description": "Setup applicative logs index template in the dev console", + "index-template": "https://github.com/opensearch-project/opensearch-catalog/tree/main/integrations/observability/java_client/schemas/applicative-logs-1.0.0.mapping.json", + "index-pattern-name": "applicative_logs-*" + } + ], + "index-patterns": { + "type": [ + "logs" + ], + "info": [ + "https://opensearch.org/docs/latest/dashboards/management/index-patterns/" + ], + "description": "Import index patterns `.ndjson` file to the saved objects", + "index-pattern": "https://github.com/opensearch-project/opensearch-catalog/tree/main/integrations/observability/java_client/assets/tutorial-1.0.0.ndjson", + "index-patterns-name": [ + "applicative_logs-*" + ] + }, + "sampleData": { + "path": "sample.json" + } +} \ No newline at end of file diff --git a/integrations/observability/java_client/getting-started/java-app/Dockerfile b/integrations/observability/java_client/getting-started/java-app/Dockerfile new file mode 100644 index 0000000..3d3e25c --- /dev/null +++ b/integrations/observability/java_client/getting-started/java-app/Dockerfile @@ -0,0 +1,16 @@ +FROM maven:3.8.4-openjdk-11-slim AS build + +WORKDIR /app + +COPY pom.xml . +COPY src ./src + +RUN mvn clean package + +FROM openjdk:11-slim + +WORKDIR /app + +COPY --from=build /app/target/java-app-1.0-SNAPSHOT.jar app.jar + +CMD ["java", "-jar", "app.jar"] diff --git a/integrations/observability/java_client/getting-started/java-app/pom.xml b/integrations/observability/java_client/getting-started/java-app/pom.xml new file mode 100644 index 0000000..50bb784 --- /dev/null +++ b/integrations/observability/java_client/getting-started/java-app/pom.xml @@ -0,0 +1,51 @@ + + 4.0.0 + com.example + java-app + 1.0-SNAPSHOT + + 11 + 11 + + + + org.json + json + 20210307 + + + + + + org.apache.maven.plugins + maven-jar-plugin + 3.1.0 + + + + com.example.App + + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.2.4 + + + package + + shade + + + false + + + + + + + diff --git a/integrations/observability/java_client/getting-started/java-app/src/main/java/App.java b/integrations/observability/java_client/getting-started/java-app/src/main/java/App.java new file mode 100644 index 0000000..8b819fb --- /dev/null +++ b/integrations/observability/java_client/getting-started/java-app/src/main/java/App.java @@ -0,0 +1,58 @@ +package com.example; + +import org.json.JSONObject; + +import java.io.FileWriter; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Random; +import java.util.Timer; +import java.util.TimerTask; + +public class App { + public static void main(String[] args) { + Timer timer = new Timer(); + timer.schedule(new LogTask(), 0, 5000); // Generate a log every 5 seconds + } +} + +class LogTask extends TimerTask { + private static final String LOG_FILE = "/logs/app.log"; + private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); + private static final Random random = new Random(); + + private static final String[] messages = { + "Application started successfully.", + "User logged in.", + "Error accessing database.", + "File not found.", + "Connection timeout.", + "User logged out.", + "Data saved successfully." + }; + + private static final String[] levels = { + "info", + "error", + "warning", + "debug" + }; + + @Override + public void run() { + JSONObject logEntry = new JSONObject(); + logEntry.put("timestamp", sdf.format(new Date())); + logEntry.put("level", levels[random.nextInt(levels.length)]); + logEntry.put("message", messages[random.nextInt(messages.length)]); + logEntry.put("source", "your_java_project"); + logEntry.put("module", "main"); + logEntry.put("function", "start_app"); + + try (FileWriter file = new FileWriter(LOG_FILE, true)) { + file.write(logEntry.toString() + "\n"); + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/integrations/observability/java_client/getting-started/opensearch_dashboards.yml b/integrations/observability/java_client/getting-started/opensearch_dashboards.yml new file mode 100644 index 0000000..e386ddb --- /dev/null +++ b/integrations/observability/java_client/getting-started/opensearch_dashboards.yml @@ -0,0 +1,10 @@ +opensearch.hosts: ["https://opensearch-node1:9200"] +server.host: 0.0.0.0 +opensearch.ssl.verificationMode: none +opensearch.username: "admin" +opensearch.password: "my_%New%_passW0rd!@#" +opensearch.requestHeadersWhitelist: [ authorization,securitytenant ] +opensearch_security.multitenancy.enabled: false +opensearch_security.multitenancy.tenants.preferred: ["Private", "Global"] +opensearch_security.readonly_mode.roles: ["kibana_read_only"] +vis_type_vega.enableExternalUrls: true diff --git a/integrations/observability/java_client/java_client-1.0.0.json b/integrations/observability/java_client/java_client-1.0.0.json new file mode 100644 index 0000000..cafb53b --- /dev/null +++ b/integrations/observability/java_client/java_client-1.0.0.json @@ -0,0 +1,38 @@ +{ + "name": "java-client", + "version": "1.0.0", + "displayName": "java client", + "description": "java applicative logs", + "license": "Apache-2.0", + "type": "logs", + "labels": ["Observability", "Logs", "java"], + "author": "OpenSearch", + "sourceUrl": "https://github.com/opensearch-project/opensearch-catalog/tree/main/integrations/observability/java_client", + "workflows": [ + { + "name": "dashboards", + "label": "Dashboards & Visualizations", + "description": "Dashboards and indices that enable you to easily visualize important metrics.", + "enabled_by_default": true + } + ], + "statics": { + "logo": { + "annotation": "java Logo", + "path": "logo.svg" + }, + "gallery": [ + { + "annotation": "java Client Tutorial Dashboard", + "path": "dashboard.png" + } + ] + }, + "components": [], + "assets": [ + { "name": "tutorial", "version": "1.0.0", "extension": "ndjson", "type": "savedObjectBundle", "workflows": ["dashboards"] } + ], + "sampleData": { + "path": "sample.json" + } +} \ No newline at end of file diff --git a/integrations/observability/java_client/schemas/applicative-logs-1.0.0.mapping.json b/integrations/observability/java_client/schemas/applicative-logs-1.0.0.mapping.json new file mode 100644 index 0000000..cc2d081 --- /dev/null +++ b/integrations/observability/java_client/schemas/applicative-logs-1.0.0.mapping.json @@ -0,0 +1,36 @@ +{ + "index_patterns": ["applicative_logs-*"], + "template": { + "settings": { + "number_of_shards": 1 + }, + "mappings": { + "properties": { + "timestamp": { + "type": "date" + }, + "level": { + "type": "keyword" + }, + "message": { + "type": "text" + }, + "source": { + "type": "keyword" + }, + "module": { + "type": "keyword" + }, + "function": { + "type": "keyword" + }, + "error_code": { + "type": "keyword" + }, + "user_id": { + "type": "keyword" + } + } + } + } +} diff --git a/integrations/observability/java_client/static/dashboard.png b/integrations/observability/java_client/static/dashboard.png new file mode 100644 index 0000000..3a951a9 Binary files /dev/null and b/integrations/observability/java_client/static/dashboard.png differ