From d26398fe7f9cf56aa4057e5a81f56c671a6ab8bb Mon Sep 17 00:00:00 2001 From: Marco Ziccardi <marco.ziccard@gmail.com> Date: Fri, 26 Aug 2016 15:13:35 +0200 Subject: [PATCH] Add snippets to Logging's javadoc, LoggingSnippets class and tests --- .../logging/snippets/LoggingSnippets.java | 545 ++++++++++++++++++ .../logging/snippets/ITLoggingSnippets.java | 172 ++++++ .../com/google/cloud/logging/Logging.java | 325 +++++++++++ 3 files changed, 1042 insertions(+) create mode 100644 gcloud-java-examples/src/main/java/com/google/cloud/examples/logging/snippets/LoggingSnippets.java create mode 100644 gcloud-java-examples/src/test/java/com/google/cloud/examples/logging/snippets/ITLoggingSnippets.java diff --git a/gcloud-java-examples/src/main/java/com/google/cloud/examples/logging/snippets/LoggingSnippets.java b/gcloud-java-examples/src/main/java/com/google/cloud/examples/logging/snippets/LoggingSnippets.java new file mode 100644 index 000000000000..7e9a17d0d750 --- /dev/null +++ b/gcloud-java-examples/src/main/java/com/google/cloud/examples/logging/snippets/LoggingSnippets.java @@ -0,0 +1,545 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * EDITING INSTRUCTIONS + * This file is referenced in Logging's javadoc. Any change to this file should be reflected in + * Logging's javadoc. + */ + +package com.google.cloud.examples.logging.snippets; + +import com.google.cloud.AsyncPage; +import com.google.cloud.MonitoredResource; +import com.google.cloud.MonitoredResourceDescriptor; +import com.google.cloud.Page; +import com.google.cloud.logging.LogEntry; +import com.google.cloud.logging.Logging; +import com.google.cloud.logging.Logging.EntryListOption; +import com.google.cloud.logging.Logging.ListOption; +import com.google.cloud.logging.Logging.WriteOption; +import com.google.cloud.logging.LoggingOptions; +import com.google.cloud.logging.Metric; +import com.google.cloud.logging.MetricInfo; +import com.google.cloud.logging.Payload.JsonPayload; +import com.google.cloud.logging.Payload.StringPayload; +import com.google.cloud.logging.Sink; +import com.google.cloud.logging.SinkInfo; +import com.google.cloud.logging.SinkInfo.Destination.DatasetDestination; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +public class LoggingSnippets { + + private final Logging logging; + + public LoggingSnippets(Logging logging) { + this.logging = logging; + } + + /** + * Example of creating a sink to export logs to a BigQuery dataset (in the + * {@link LoggingOptions#projectId()} project). + */ + // [TARGET create(SinkInfo)] + // [VARIABLE "my_sink_name"] + // [VARIABLE "my_dataset"] + public Sink createSink(String sinkName, String datasetName) { + // [START createSink] + SinkInfo sinkInfo = SinkInfo.of(sinkName, DatasetDestination.of(datasetName)); + Sink sink = logging.create(sinkInfo); + // [END createSink] + return sink; + } + + /** + * Example of asynchronously creating a sink to export logs to a BigQuery dataset (in the + * {@link LoggingOptions#projectId()} project). + */ + // [TARGET createAsync(SinkInfo)] + // [VARIABLE "my_sink_name"] + // [VARIABLE "my_dataset"] + public Sink createSinkAsync(String sinkName, String datasetName) + throws ExecutionException, InterruptedException { + // [START createSinkAsync] + SinkInfo sinkInfo = SinkInfo.of(sinkName, DatasetDestination.of(datasetName)); + Future<Sink> future = logging.createAsync(sinkInfo); + // ... + Sink sink = future.get(); + // [END createSinkAsync] + return sink; + } + + /** + * Example of updating a sink. + */ + // [TARGET update(SinkInfo)] + // [VARIABLE "my_sink_name"] + // [VARIABLE "my_dataset"] + public Sink updateSink(String sinkName, String datasetName) { + // [START updateSink] + SinkInfo sinkInfo = SinkInfo.builder(sinkName, DatasetDestination.of(datasetName)) + .versionFormat(SinkInfo.VersionFormat.V2) + .filter("severity>=ERROR") + .build(); + Sink sink = logging.update(sinkInfo); + // [END updateSink] + return sink; + } + + /** + * Example of asynchronously updating a sink. + */ + // [TARGET updateAsync(SinkInfo)] + // [VARIABLE "my_sink_name"] + // [VARIABLE "my_dataset"] + public Sink updateSinkAsync(String sinkName, String datasetName) + throws ExecutionException, InterruptedException { + // [START updateSinkAsync] + SinkInfo sinkInfo = SinkInfo.builder(sinkName, DatasetDestination.of(datasetName)) + .versionFormat(SinkInfo.VersionFormat.V2) + .filter("severity>=ERROR") + .build(); + Future<Sink> future = logging.updateAsync(sinkInfo); + // ... + Sink sink = future.get(); + // [END updateSinkAsync] + return sink; + } + + /** + * Example of getting a sink. + */ + // [TARGET getSink(String)] + // [VARIABLE "my_sink_name"] + public Sink getSink(String sinkName) { + // [START getSink] + Sink sink = logging.getSink(sinkName); + if (sink != null) { + // sink was not found + } + // [END getSink] + return sink; + } + + /** + * Example of asynchronously getting a sink. + */ + // [TARGET getSinkAsync(String)] + // [VARIABLE "my_sink_name"] + public Sink getSinkAsync(String sinkName) throws ExecutionException, InterruptedException { + // [START getSinkAsync] + Future<Sink> future = logging.getSinkAsync(sinkName); + // ... + Sink sink = future.get(); + if (sink != null) { + // sink was not found + } + // [END getSinkAsync] + return sink; + } + + /** + * Example of listing sinks, specifying the page size. + */ + // [TARGET listSinks(ListOption...)] + public Page<Sink> listSinks() { + // [START listSinks] + Page<Sink> sinks = logging.listSinks(ListOption.pageSize(100)); + Iterator<Sink> sinkIterator = sinks.iterateAll(); + while (sinkIterator.hasNext()) { + Sink sink = sinkIterator.next(); + // do something with the sink + } + // [END listSinks] + return sinks; + } + + /** + * Example of asynchronously listing sinks, specifying the page size. + */ + // [TARGET listSinksAsync(ListOption...)] + public Page<Sink> listSinksAsync() throws ExecutionException, InterruptedException { + // [START listSinksAsync] + Future<AsyncPage<Sink>> future = logging.listSinksAsync(ListOption.pageSize(100)); + // ... + AsyncPage<Sink> sinks = future.get(); + Iterator<Sink> sinkIterator = sinks.iterateAll(); + while (sinkIterator.hasNext()) { + Sink sink = sinkIterator.next(); + // do something with the sink + } + // [END listSinksAsync] + return sinks; + } + + /** + * Example of deleting a sink. + */ + // [TARGET deleteSink(String)] + // [VARIABLE "my_sink_name"] + public boolean deleteSink(String sinkName) { + // [START deleteSink] + boolean deleted = logging.deleteSink(sinkName); + if (deleted) { + // the sink was deleted + } else { + // the sink was not found + } + // [END deleteSink] + return deleted; + } + + /** + * Example of asynchronously deleting a sink. + */ + // [TARGET deleteSinkAsync(String)] + // [VARIABLE "my_sink_name"] + public boolean deleteSinkAsync(String sinkName) throws ExecutionException, InterruptedException { + // [START deleteSinkAsync] + Future<Boolean> future = logging.deleteSinkAsync(sinkName); + // ... + boolean deleted = future.get(); + if (deleted) { + // the sink was deleted + } else { + // the sink was not found + } + // [END deleteSinkAsync] + return deleted; + } + + /** + * Example of deleting a log. + */ + // [TARGET deleteLog(String)] + // [VARIABLE "my_log_name"] + public boolean deleteLog(String logName) { + // [START deleteLog] + boolean deleted = logging.deleteLog(logName); + if (deleted) { + // the log was deleted + } else { + // the log was not found + } + // [END deleteLog] + return deleted; + } + + /** + * Example of asynchronously deleting a log. + */ + // [TARGET deleteLogAsync(String)] + // [VARIABLE "my_log_name"] + public boolean deleteLogAsync(String logName) throws ExecutionException, InterruptedException { + // [START deleteLogAsync] + Future<Boolean> future = logging.deleteLogAsync(logName); + // ... + boolean deleted = future.get(); + if (deleted) { + // the log was deleted + } else { + // the log was not found + } + // [END deleteLogAsync] + return deleted; + } + + /** + * Example of listing monitored resource descriptors, specifying the page size. + */ + // [TARGET listMonitoredResourceDescriptors(ListOption...)] + public Page<MonitoredResourceDescriptor> listMonitoredResourceDescriptors() { + // [START listMonitoredResourceDescriptors] + Page<MonitoredResourceDescriptor> descriptors = + logging.listMonitoredResourceDescriptors(ListOption.pageSize(100)); + Iterator<MonitoredResourceDescriptor> descriptorIterator = descriptors.iterateAll(); + while (descriptorIterator.hasNext()) { + MonitoredResourceDescriptor descriptor = descriptorIterator.next(); + // do something with the descriptor + } + // [END listMonitoredResourceDescriptors] + return descriptors; + } + + /** + * Example of asynchronously listing monitored resource descriptors, specifying the page size. + */ + // [TARGET listMonitoredResourceDescriptorsAsync(ListOption...)] + public Page<MonitoredResourceDescriptor> listMonitoredResourceDescriptorsAsync() + throws ExecutionException, InterruptedException { + // [START listMonitoredResourceDescriptorsAsync] + Future<AsyncPage<MonitoredResourceDescriptor>> future = + logging.listMonitoredResourceDescriptorsAsync(ListOption.pageSize(100)); + // ... + AsyncPage<MonitoredResourceDescriptor> descriptors = future.get(); + Iterator<MonitoredResourceDescriptor> descriptorIterator = descriptors.iterateAll(); + while (descriptorIterator.hasNext()) { + MonitoredResourceDescriptor descriptor = descriptorIterator.next(); + // do something with the descriptor + } + // [END listMonitoredResourceDescriptorsAsync] + return descriptors; + } + + /** + * Example of creating a metric for logs with severity higher or equal to ERROR. + */ + // [TARGET create(MetricInfo)] + // [VARIABLE "my_metric_name"] + public Metric createMetric(String metricName) { + // [START createMetric] + MetricInfo metricInfo = MetricInfo.of(metricName, "severity>=ERROR"); + Metric metric = logging.create(metricInfo); + // [END createMetric] + return metric; + } + + /** + * Example of asynchronously creating a metric for logs with severity higher or equal to ERROR. + */ + // [TARGET createAsync(MetricInfo)] + // [VARIABLE "my_metric_name"] + public Metric createMetricAsync(String metricName) + throws ExecutionException, InterruptedException { + // [START createMetricAsync] + MetricInfo metricInfo = MetricInfo.of(metricName, "severity>=ERROR"); + Future<Metric> future = logging.createAsync(metricInfo); + // ... + Metric metric = future.get(); + // [END createMetricAsync] + return metric; + } + + /** + * Example of updating a metric. + */ + // [TARGET update(MetricInfo)] + // [VARIABLE "my_metric_name"] + public Metric updateMetric(String metricName) { + // [START updateMetric] + MetricInfo metricInfo = MetricInfo.builder(metricName, "severity>=ERROR") + .description("new description") + .build(); + Metric metric = logging.update(metricInfo); + // [END updateMetric] + return metric; + } + + /** + * Example of asynchronously updating a metric. + */ + // [TARGET updateAsync(MetricInfo)] + // [VARIABLE "my_metric_name"] + public Metric updateMetricAsync(String metricName) + throws ExecutionException, InterruptedException { + // [START updateMetricAsync] + MetricInfo metricInfo = MetricInfo.builder(metricName, "severity>=ERROR") + .description("new description") + .build(); + Future<Metric> future = logging.updateAsync(metricInfo); + // ... + Metric metric = future.get(); + // [END updateMetricAsync] + return metric; + } + + /** + * Example of getting a metric. + */ + // [TARGET getMetric(String)] + // [VARIABLE "my_metric_name"] + public Metric getMetric(String metricName) { + // [START getMetric] + Metric metric = logging.getMetric(metricName); + if (metric != null) { + // metric was not found + } + // [END getMetric] + return metric; + } + + /** + * Example of asynchronously getting a metric. + */ + // [TARGET getMetricAsync(String)] + // [VARIABLE "my_metric_name"] + public Metric getMetricAsync(String metricName) throws ExecutionException, InterruptedException { + // [START getMetricAsync] + Future<Metric> future = logging.getMetricAsync(metricName); + // ... + Metric metric = future.get(); + if (metric != null) { + // metric was not found + } + // [END getMetricAsync] + return metric; + } + + /** + * Example of listing metrics, specifying the page size. + */ + // [TARGET listMetrics(ListOption...)] + public Page<Metric> listMetrics() { + // [START listMetrics] + Page<Metric> metrics = logging.listMetrics(ListOption.pageSize(100)); + Iterator<Metric> metricIterator = metrics.iterateAll(); + while (metricIterator.hasNext()) { + Metric metric = metricIterator.next(); + // do something with the metric + } + // [END listMetrics] + return metrics; + } + + /** + * Example of asynchronously listing metrics, specifying the page size. + */ + // [TARGET listMetricsAsync(ListOption...)] + public Page<Metric> listMetricsAsync() throws ExecutionException, InterruptedException { + // [START listMetricsAsync] + Future<AsyncPage<Metric>> future = logging.listMetricsAsync(ListOption.pageSize(100)); + // ... + AsyncPage<Metric> metrics = future.get(); + Iterator<Metric> metricIterator = metrics.iterateAll(); + while (metricIterator.hasNext()) { + Metric metric = metricIterator.next(); + // do something with the metric + } + // [END listMetricsAsync] + return metrics; + } + + /** + * Example of deleting a metric. + */ + // [TARGET deleteMetric(String)] + // [VARIABLE "my_metric_name"] + public boolean deleteMetric(String metricName) { + // [START deleteMetric] + boolean deleted = logging.deleteMetric(metricName); + if (deleted) { + // the metric was deleted + } else { + // the metric was not found + } + // [END deleteMetric] + return deleted; + } + + /** + * Example of asynchronously deleting a metric. + */ + // [TARGET deleteMetricAsync(String)] + // [VARIABLE "my_metric_name"] + public boolean deleteMetricAsync(String metricName) + throws ExecutionException, InterruptedException { + // [START deleteMetricAsync] + Future<Boolean> future = logging.deleteMetricAsync(metricName); + // ... + boolean deleted = future.get(); + if (deleted) { + // the metric was deleted + } else { + // the metric was not found + } + // [END deleteMetricAsync] + return deleted; + } + + /** + * Example of writing log entries and providing a default log name and monitored resource. + */ + // [TARGET write(Iterable, WriteOption...)] + // [VARIABLE "my_log_name"] + public void write(String logName) { + // [START write] + List<LogEntry> entries = new ArrayList<>(); + entries.add(LogEntry.of(StringPayload.of("Entry payload"))); + Map<String, Object> jsonMap = new HashMap<>(); + jsonMap.put("key", "value"); + entries.add(LogEntry.of(JsonPayload.of(jsonMap))); + logging.write(entries, + WriteOption.logName(logName), + WriteOption.resource(MonitoredResource.builder("global").build())); + // [END write] + } + + /** + * Example of asynchronously writing log entries and providing a default log name and monitored + * resource. + */ + // [TARGET writeAsync(Iterable, WriteOption...)] + // [VARIABLE "my_log_name"] + public Future<Void> writeAsync(String logName) { + // [START writeAsync] + List<LogEntry> entries = new ArrayList<>(); + entries.add(LogEntry.of(StringPayload.of("Entry payload"))); + Map<String, Object> jsonMap = new HashMap<>(); + jsonMap.put("key", "value"); + entries.add(LogEntry.of(JsonPayload.of(jsonMap))); + Future<Void> future = logging.writeAsync( + entries, + WriteOption.logName(logName), + WriteOption.resource(MonitoredResource.builder("global").build())); + // [END writeAsync] + return future; + } + + /** + * Example of listing log entries for a specific log. + */ + // [TARGET listLogEntries(EntryListOption...)] + // [VARIABLE "logName=projects/my_project_id/logs/my_log_name"] + public Page<LogEntry> listLogEntries(String filter) { + // [START listLogEntries] + Page<LogEntry> entries = logging.listLogEntries(EntryListOption.filter(filter)); + Iterator<LogEntry> entryIterator = entries.iterateAll(); + while (entryIterator.hasNext()) { + LogEntry entry = entryIterator.next(); + // do something with the entry + } + // [END listLogEntries] + return entries; + } + + /** + * Example of asynchronously listing log entries for a specific log. + */ + // [TARGET listLogEntriesAsync(EntryListOption...)] + // [VARIABLE "logName=projects/my_project_id/logs/my_log_name"] + public Page<LogEntry> listLogEntriesAsync(String filter) + throws ExecutionException, InterruptedException { + // [START listLogEntriesAsync] + Future<AsyncPage<LogEntry>> future = + logging.listLogEntriesAsync(EntryListOption.filter(filter)); + // ... + AsyncPage<LogEntry> entries = future.get(); + Iterator<LogEntry> entryIterator = entries.iterateAll(); + while (entryIterator.hasNext()) { + LogEntry entry = entryIterator.next(); + // do something with the entry + } + // [END listLogEntriesAsync] + return entries; + } +} diff --git a/gcloud-java-examples/src/test/java/com/google/cloud/examples/logging/snippets/ITLoggingSnippets.java b/gcloud-java-examples/src/test/java/com/google/cloud/examples/logging/snippets/ITLoggingSnippets.java new file mode 100644 index 000000000000..dea50e532726 --- /dev/null +++ b/gcloud-java-examples/src/test/java/com/google/cloud/examples/logging/snippets/ITLoggingSnippets.java @@ -0,0 +1,172 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.examples.logging.snippets; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import com.google.cloud.MonitoredResourceDescriptor; +import com.google.cloud.logging.LogEntry; +import com.google.cloud.logging.Logging; +import com.google.cloud.logging.Metric; +import com.google.cloud.logging.Sink; +import com.google.cloud.logging.testing.RemoteLoggingHelper; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterators; +import com.google.common.collect.Sets; + +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.rules.Timeout; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; +import java.util.concurrent.ExecutionException; + +public class ITLoggingSnippets { + + private static final String DATASET = "dataset"; + private static final Set<String> DESCRIPTOR_TYPES = ImmutableSet.of("gce_instance", "gae_app", + "cloudsql_database", "api", "gcs_bucket", "global", "dataflow_step", "build", + "app_script_function", "dataproc_cluster", "ml_job", "bigquery_resource", + "crm_iam_policy_check", "container", "gke_cluster", "cloud_debugger_resource", + "http_load_balancer", "aws_ec2_instance", "client_auth_config_brand", + "client_auth_config_client", "logging_log", "logging_sink", "metric", "project", + "testservice_matrix", "service_account", "deployment", "dns_managed_zone"); + + private static Logging logging; + private static LoggingSnippets loggingSnippets; + + @Rule + public Timeout globalTimeout = Timeout.seconds(300); + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @BeforeClass + public static void beforeClass() { + RemoteLoggingHelper helper = RemoteLoggingHelper.create(); + logging = helper.options().service(); + loggingSnippets = new LoggingSnippets(logging); + } + + @Test + public void testSink() throws ExecutionException, InterruptedException { + String sinkName1 = RemoteLoggingHelper.formatForTest("sink_name1"); + String sinkName2 = RemoteLoggingHelper.formatForTest("sink_name2"); + Sink sink1 = loggingSnippets.createSink(sinkName1, DATASET); + Sink sink2 = loggingSnippets.createSinkAsync(sinkName2, DATASET); + assertNotNull(sink1); + assertNotNull(sink2); + sink1 = loggingSnippets.getSink(sinkName1); + sink2 = loggingSnippets.getSinkAsync(sinkName2); + assertNotNull(sink1); + assertNotNull(sink2); + sink1 = loggingSnippets.updateSink(sinkName1, DATASET); + sink2 = loggingSnippets.updateSinkAsync(sinkName2, DATASET); + Set<Sink> sinks = Sets.newHashSet(loggingSnippets.listSinks().iterateAll()); + while (!sinks.contains(sink1) || !sinks.contains(sink2)) { + Thread.sleep(500); + sinks = Sets.newHashSet(loggingSnippets.listSinks().iterateAll()); + } + sinks = Sets.newHashSet(loggingSnippets.listSinksAsync().iterateAll()); + while (!sinks.contains(sink1) || !sinks.contains(sink2)) { + Thread.sleep(500); + sinks = Sets.newHashSet(loggingSnippets.listSinksAsync().iterateAll()); + } + assertTrue(loggingSnippets.deleteSink(sinkName1)); + assertTrue(loggingSnippets.deleteSinkAsync(sinkName2)); + } + + @Test + public void testMetric() throws ExecutionException, InterruptedException { + String metricName1 = RemoteLoggingHelper.formatForTest("metric_name1"); + String metricName2 = RemoteLoggingHelper.formatForTest("metric_name2"); + Metric metric1 = loggingSnippets.createMetric(metricName1); + Metric metric2 = loggingSnippets.createMetricAsync(metricName2); + assertNotNull(metric1); + assertNotNull(metric2); + metric1 = loggingSnippets.getMetric(metricName1); + metric2 = loggingSnippets.getMetricAsync(metricName2); + assertNotNull(metric1); + assertNotNull(metric2); + metric1 = loggingSnippets.updateMetric(metricName1); + metric2 = loggingSnippets.updateMetricAsync(metricName2); + Set<Metric> metrics = Sets.newHashSet(loggingSnippets.listMetrics().iterateAll()); + while (!metrics.contains(metric1) || !metrics.contains(metric2)) { + Thread.sleep(500); + metrics = Sets.newHashSet(loggingSnippets.listMetrics().iterateAll()); + } + metrics = Sets.newHashSet(loggingSnippets.listMetricsAsync().iterateAll()); + while (!metrics.contains(metric1) || !metrics.contains(metric2)) { + Thread.sleep(500); + metrics = Sets.newHashSet(loggingSnippets.listMetricsAsync().iterateAll()); + } + assertTrue(loggingSnippets.deleteMetric(metricName1)); + assertTrue(loggingSnippets.deleteMetricAsync(metricName2)); + } + + @Test + public void testMonitoredResourceDescriptor() throws ExecutionException, InterruptedException { + Iterator<MonitoredResourceDescriptor> iterator = + loggingSnippets.listMonitoredResourceDescriptors().iterateAll(); + Set<String> descriptorTypes = new HashSet<>(); + while (iterator.hasNext()) { + descriptorTypes.add(iterator.next().type()); + } + for (String type : DESCRIPTOR_TYPES) { + assertTrue(descriptorTypes.contains(type)); + } + iterator = loggingSnippets.listMonitoredResourceDescriptorsAsync().iterateAll(); + descriptorTypes.clear(); + while (iterator.hasNext()) { + descriptorTypes.add(iterator.next().type()); + } + for (String type : DESCRIPTOR_TYPES) { + assertTrue(descriptorTypes.contains(type)); + } + } + + @Test + public void testWriteAndListLogEntries() throws InterruptedException { + String logName = RemoteLoggingHelper.formatForTest("log_name"); + String filter = "logName=projects/" + logging.options().projectId() + "/logs/" + logName; + loggingSnippets.write(logName); + Iterator<LogEntry> iterator = loggingSnippets.listLogEntries(filter).iterateAll(); + while (Iterators.size(iterator) < 2) { + Thread.sleep(500); + iterator = loggingSnippets.listLogEntries(filter).iterateAll(); + } + assertTrue(loggingSnippets.deleteLog(logName)); + } + + @Test + public void testWriteAndListLogEntriesAsync() throws ExecutionException, InterruptedException { + String logName = RemoteLoggingHelper.formatForTest("log_name"); + String filter = "logName=projects/" + logging.options().projectId() + "/logs/" + logName; + loggingSnippets.writeAsync(logName).get(); + Iterator<LogEntry> iterator = loggingSnippets.listLogEntriesAsync(filter).iterateAll(); + while (Iterators.size(iterator) < 2) { + Thread.sleep(500); + iterator = loggingSnippets.listLogEntriesAsync(filter).iterateAll(); + } + assertTrue(loggingSnippets.deleteLogAsync(logName)); + } +} diff --git a/gcloud-java-logging/src/main/java/com/google/cloud/logging/Logging.java b/gcloud-java-logging/src/main/java/com/google/cloud/logging/Logging.java index 454590aacd7d..2f4b9c0b1cb7 100644 --- a/gcloud-java-logging/src/main/java/com/google/cloud/logging/Logging.java +++ b/gcloud-java-logging/src/main/java/com/google/cloud/logging/Logging.java @@ -195,6 +195,15 @@ public static EntryListOption filter(String filter) { /** * Creates a new sink. * + * <p>Example of creating a sink to export logs to a BigQuery dataset (in the + * {@link LoggingOptions#projectId()} project). + * <pre> {@code + * String sinkName = "my_sink_name"; + * String datasetName = "my_dataset"; + * SinkInfo sinkInfo = SinkInfo.of(sinkName, DatasetDestination.of(datasetName)); + * Sink sink = logging.create(sinkInfo); + * }</pre> + * * @return the created sink * @throws LoggingException upon failure */ @@ -203,12 +212,35 @@ public static EntryListOption filter(String filter) { /** * Sends a request for creating a sink. This method returns a {@code Future} object to consume the * result. {@link Future#get()} returns the created sink. + * + * <p>Example of asynchronously creating a sink to export logs to a BigQuery dataset (in the + * {@link LoggingOptions#projectId()} project). + * <pre> {@code + * String sinkName = "my_sink_name"; + * String datasetName = "my_dataset"; + * SinkInfo sinkInfo = SinkInfo.of(sinkName, DatasetDestination.of(datasetName)); + * Future<Sink> future = logging.createAsync(sinkInfo); + * // ... + * Sink sink = future.get(); + * }</pre> + * */ Future<Sink> createAsync(SinkInfo sink); /** * Updates a sink or creates one if it does not exist. * + * <p>Example of updating a sink. + * <pre> {@code + * String sinkName = "my_sink_name"; + * String datasetName = "my_dataset"; + * SinkInfo sinkInfo = SinkInfo.builder(sinkName, DatasetDestination.of(datasetName)) + * .versionFormat(SinkInfo.VersionFormat.V2) + * .filter("severity>=ERROR") + * .build(); + * Sink sink = logging.update(sinkInfo); + * }</pre> + * * @return the created sink * @throws LoggingException upon failure */ @@ -218,12 +250,35 @@ public static EntryListOption filter(String filter) { * Sends a request for updating a sink (or creating it, if it does not exist). This method returns * a {@code Future} object to consume the result. {@link Future#get()} returns the * updated/created sink or {@code null} if not found. + * + * <p>Example of asynchronously updating a sink. + * <pre> {@code + * String sinkName = "my_sink_name"; + * String datasetName = "my_dataset"; + * SinkInfo sinkInfo = SinkInfo.builder(sinkName, DatasetDestination.of(datasetName)) + * .versionFormat(SinkInfo.VersionFormat.V2) + * .filter("severity>=ERROR") + * .build(); + * Future<Sink> future = logging.updateAsync(sinkInfo); + * // ... + * Sink sink = future.get(); + * }</pre> + * */ Future<Sink> updateAsync(SinkInfo sink); /** * Returns the requested sink or {@code null} if not found. * + * <p>Example of getting a sink. + * <pre> {@code + * String sinkName = "my_sink_name"; + * Sink sink = logging.getSink(sinkName); + * if (sink != null) { + * // sink was not found + * } + * }</pre> + * * @throws LoggingException upon failure */ Sink getSink(String sink); @@ -232,6 +287,17 @@ public static EntryListOption filter(String filter) { * Sends a request for getting a sink. This method returns a {@code Future} object to consume the * result. {@link Future#get()} returns the requested sink or {@code null} if not found. * + * <p>Example of asynchronously getting a sink. + * <pre> {@code + * String sinkName = "my_sink_name"; + * Future<Sink> future = logging.getSinkAsync(sinkName); + * // ... + * Sink sink = future.get(); + * if (sink != null) { + * // sink was not found + * } + * }</pre> + * * @throws LoggingException upon failure */ Future<Sink> getSinkAsync(String sink); @@ -241,6 +307,16 @@ public static EntryListOption filter(String filter) { * paginated results. Use {@link ListOption} to specify the page size or the page token from which * to start listing sinks. * + * <p>Example of listing sinks, specifying the page size. + * <pre> {@code + * Page<Sink> sinks = logging.listSinks(ListOption.pageSize(100)); + * Iterator<Sink> sinkIterator = sinks.iterateAll(); + * while (sinkIterator.hasNext()) { + * Sink sink = sinkIterator.next(); + * // do something with the sink + * } + * }</pre> + * * @throws LoggingException upon failure */ Page<Sink> listSinks(ListOption... options); @@ -250,12 +326,36 @@ public static EntryListOption filter(String filter) { * the result. {@link Future#get()} returns an {@link AsyncPage} object that can be used to * asynchronously handle paginated results. Use {@link ListOption} to specify the page size or the * page token from which to start listing sinks. + * + * <p>Example of asynchronously listing sinks, specifying the page size. + * <pre> {@code + * Future<AsyncPage<Sink>> future = logging.listSinksAsync(ListOption.pageSize(100)); + * // ... + * AsyncPage<Sink> sinks = future.get(); + * Iterator<Sink> sinkIterator = sinks.iterateAll(); + * while (sinkIterator.hasNext()) { + * Sink sink = sinkIterator.next(); + * // do something with the sink + * } + * }</pre> + * */ Future<AsyncPage<Sink>> listSinksAsync(ListOption... options); /** * Deletes the requested sink. * + * <p>Example of deleting a sink. + * <pre> {@code + * String sinkName = "my_sink_name"; + * boolean deleted = logging.deleteSink(sinkName); + * if (deleted) { + * // the sink was deleted + * } else { + * // the sink was not found + * } + * }</pre> + * * @return {@code true} if the sink was deleted, {@code false} if it was not found */ boolean deleteSink(String sink); @@ -264,12 +364,37 @@ public static EntryListOption filter(String filter) { * Sends a request for deleting a sink. This method returns a {@code Future} object to consume the * result. {@link Future#get()} returns {@code true} if the sink was deleted, {@code false} if it * was not found. + * + * <p>Example of asynchronously deleting a sink. + * <pre> {@code + * String sinkName = "my_sink_name"; + * Future<Boolean> future = logging.deleteSinkAsync(sinkName); + * // ... + * boolean deleted = future.get(); + * if (deleted) { + * // the sink was deleted + * } else { + * // the sink was not found + * } + * }</pre> + * */ Future<Boolean> deleteSinkAsync(String sink); /** * Deletes a log and all its log entries. The log will reappear if new entries are written to it. * + * <p>Example of deleting a log. + * <pre> {@code + * String logName = "my_log_name"; + * boolean deleted = logging.deleteLog(logName); + * if (deleted) { + * // the log was deleted + * } else { + * // the log was not found + * } + * }</pre> + * * @return {@code true} if the log was deleted, {@code false} if it was not found */ boolean deleteLog(String log); @@ -278,6 +403,20 @@ public static EntryListOption filter(String filter) { * Sends a request for deleting a log and all its log entries. This method returns a * {@code Future} object to consume the result. {@link Future#get()} returns {@code true} if the * log was deleted, {@code false} if it was not found. + * + * <p>Example of asynchronously deleting a log. + * <pre> {@code + * String logName = "my_log_name"; + * Future<Boolean> future = logging.deleteLogAsync(logName); + * // ... + * boolean deleted = future.get(); + * if (deleted) { + * // the log was deleted + * } else { + * // the log was not found + * } + * }</pre> + * */ Future<Boolean> deleteLogAsync(String log); @@ -286,6 +425,17 @@ public static EntryListOption filter(String filter) { * {@link Page} object that can be used to consume paginated results. Use {@link ListOption} to * specify the page size or the page token from which to start listing resource descriptors. * + * <p>Example of listing monitored resource descriptors, specifying the page size. + * <pre> {@code + * Page<MonitoredResourceDescriptor> descriptors = + * logging.listMonitoredResourceDescriptors(ListOption.pageSize(100)); + * Iterator<MonitoredResourceDescriptor> descriptorIterator = descriptors.iterateAll(); + * while (descriptorIterator.hasNext()) { + * MonitoredResourceDescriptor descriptor = descriptorIterator.next(); + * // do something with the descriptor + * } + * }</pre> + * * @throws LoggingException upon failure */ Page<MonitoredResourceDescriptor> listMonitoredResourceDescriptors(ListOption... options); @@ -296,6 +446,20 @@ public static EntryListOption filter(String filter) { * {@link AsyncPage} object that can be used to asynchronously handle paginated results. Use * {@link ListOption} to specify the page size or the page token from which to start listing * resource descriptors. + * + * <p>Example of asynchronously listing monitored resource descriptors, specifying the page size. + * <pre> {@code + * Future<AsyncPage<MonitoredResourceDescriptor>> future = + * logging.listMonitoredResourceDescriptorsAsync(ListOption.pageSize(100)); + * // ... + * AsyncPage<MonitoredResourceDescriptor> descriptors = future.get(); + * Iterator<MonitoredResourceDescriptor> descriptorIterator = descriptors.iterateAll(); + * while (descriptorIterator.hasNext()) { + * MonitoredResourceDescriptor descriptor = descriptorIterator.next(); + * // do something with the descriptor + * } + * }</pre> + * */ Future<AsyncPage<MonitoredResourceDescriptor>> listMonitoredResourceDescriptorsAsync( ListOption... options); @@ -303,6 +467,13 @@ Future<AsyncPage<MonitoredResourceDescriptor>> listMonitoredResourceDescriptorsA /** * Creates a new metric. * + * <p>Example of creating a metric for logs with severity higher or equal to ERROR. + * <pre> {@code + * String metricName = "my_metric_name"; + * MetricInfo metricInfo = MetricInfo.of(metricName, "severity>=ERROR"); + * Metric metric = logging.create(metricInfo); + * }</pre> + * * @return the created metric * @throws LoggingException upon failure */ @@ -311,12 +482,31 @@ Future<AsyncPage<MonitoredResourceDescriptor>> listMonitoredResourceDescriptorsA /** * Sends a request for creating a metric. This method returns a {@code Future} object to consume * the result. {@link Future#get()} returns the created metric. + * + * <p>Example of asynchronously creating a metric for logs with severity higher or equal to ERROR. + * <pre> {@code + * String metricName = "my_metric_name"; + * MetricInfo metricInfo = MetricInfo.of(metricName, "severity>=ERROR"); + * Future<Metric> future = logging.createAsync(metricInfo); + * // ... + * Metric metric = future.get(); + * }</pre> + * */ Future<Metric> createAsync(MetricInfo metric); /** * Updates a metric or creates one if it does not exist. * + * <p>Example of updating a metric. + * <pre> {@code + * String metricName = "my_metric_name"; + * MetricInfo metricInfo = MetricInfo.builder(metricName, "severity>=ERROR") + * .description("new description") + * .build(); + * Metric metric = logging.update(metricInfo); + * }</pre> + * * @return the created metric * @throws LoggingException upon failure */ @@ -326,12 +516,33 @@ Future<AsyncPage<MonitoredResourceDescriptor>> listMonitoredResourceDescriptorsA * Sends a request for updating a metric (or creating it, if it does not exist). This method * returns a {@code Future} object to consume the result. {@link Future#get()} returns the * updated/created metric or {@code null} if not found. + * + * <p>Example of asynchronously updating a metric. + * <pre> {@code + * String metricName = "my_metric_name"; + * MetricInfo metricInfo = MetricInfo.builder(metricName, "severity>=ERROR") + * .description("new description") + * .build(); + * Future<Metric> future = logging.updateAsync(metricInfo); + * // ... + * Metric metric = future.get(); + * }</pre> + * */ Future<Metric> updateAsync(MetricInfo metric); /** * Returns the requested metric or {@code null} if not found. * + * <p>Example of getting a metric. + * <pre> {@code + * String metricName = "my_metric_name"; + * Metric metric = logging.getMetric(metricName); + * if (metric != null) { + * // metric was not found + * } + * }</pre> + * * @throws LoggingException upon failure */ Metric getMetric(String metric); @@ -340,6 +551,17 @@ Future<AsyncPage<MonitoredResourceDescriptor>> listMonitoredResourceDescriptorsA * Sends a request for getting a metric. This method returns a {@code Future} object to consume * the result. {@link Future#get()} returns the requested metric or {@code null} if not found. * + * <p>Example of asynchronously getting a metric. + * <pre> {@code + * String metricName = "my_metric_name"; + * Future<Metric> future = logging.getMetricAsync(metricName); + * // ... + * Metric metric = future.get(); + * if (metric != null) { + * // metric was not found + * } + * }</pre> + * * @throws LoggingException upon failure */ Future<Metric> getMetricAsync(String metric); @@ -349,6 +571,16 @@ Future<AsyncPage<MonitoredResourceDescriptor>> listMonitoredResourceDescriptorsA * paginated results. Use {@link ListOption} to specify the page size or the page token from which * to start listing metrics. * + * <p>Example of listing metrics, specifying the page size. + * <pre> {@code + * Page<Metric> metrics = logging.listMetrics(ListOption.pageSize(100)); + * Iterator<Metric> metricIterator = metrics.iterateAll(); + * while (metricIterator.hasNext()) { + * Metric metric = metricIterator.next(); + * // do something with the metric + * } + * }</pre> + * * @throws LoggingException upon failure */ Page<Metric> listMetrics(ListOption... options); @@ -358,12 +590,36 @@ Future<AsyncPage<MonitoredResourceDescriptor>> listMonitoredResourceDescriptorsA * the result. {@link Future#get()} returns an {@link AsyncPage} object that can be used to * asynchronously handle paginated results. Use {@link ListOption} to specify the page size or the * page token from which to start listing metrics. + * + * <p>Example of asynchronously listing metrics, specifying the page size. + * <pre> {@code + * Future<AsyncPage<Metric>> future = logging.listMetricsAsync(ListOption.pageSize(100)); + * // ... + * AsyncPage<Metric> metrics = future.get(); + * Iterator<Metric> metricIterator = metrics.iterateAll(); + * while (metricIterator.hasNext()) { + * Metric metric = metricIterator.next(); + * // do something with the metric + * } + * }</pre> + * */ Future<AsyncPage<Metric>> listMetricsAsync(ListOption... options); /** * Deletes the requested metric. * + * <p>Example of deleting a metric. + * <pre> {@code + * String metricName = "my_metric_name"; + * boolean deleted = logging.deleteMetric(metricName); + * if (deleted) { + * // the metric was deleted + * } else { + * // the metric was not found + * } + * }</pre> + * * @return {@code true} if the metric was deleted, {@code false} if it was not found */ boolean deleteMetric(String metric); @@ -372,6 +628,20 @@ Future<AsyncPage<MonitoredResourceDescriptor>> listMonitoredResourceDescriptorsA * Sends a request for deleting a metric. This method returns a {@code Future} object to consume * the result. {@link Future#get()} returns {@code true} if the metric was deleted, {@code false} * if it was not found. + * + * <p>Example of asynchronously deleting a metric. + * <pre> {@code + * String metricName = "my_metric_name"; + * Future<Boolean> future = logging.deleteMetricAsync(metricName); + * // ... + * boolean deleted = future.get(); + * if (deleted) { + * // the metric was deleted + * } else { + * // the metric was not found + * } + * }</pre> + * */ Future<Boolean> deleteMetricAsync(String metric); @@ -381,6 +651,20 @@ Future<AsyncPage<MonitoredResourceDescriptor>> listMonitoredResourceDescriptorsA * {@link WriteOption#resource(MonitoredResource)} to provide a monitored resource for those * entries that do not specify one. Use {@link WriteOption#labels(Map)} to provide some labels * to be added to every entry in {@code logEntries}. + * + * <p>Example of writing log entries and providing a default log name and monitored resource. + * <pre> {@code + * String logName = "my_log_name"; + * List<LogEntry> entries = new ArrayList<>(); + * entries.add(LogEntry.of(StringPayload.of("Entry payload"))); + * Map<String, Object> jsonMap = new HashMap<>(); + * jsonMap.put("key", "value"); + * entries.add(LogEntry.of(JsonPayload.of(jsonMap))); + * logging.write(entries, + * WriteOption.logName(logName), + * WriteOption.resource(MonitoredResource.builder("global").build())); + * }</pre> + * */ void write(Iterable<LogEntry> logEntries, WriteOption... options); @@ -391,6 +675,22 @@ Future<AsyncPage<MonitoredResourceDescriptor>> listMonitoredResourceDescriptorsA * entries that do not specify one. Use {@link WriteOption#labels(Map)} to provide some labels * to be added to every entry in {@code logEntries}. The method returns a {@code Future} object * that can be used to wait for the write operation to be completed. + * + * <p>Example of asynchronously writing log entries and providing a default log name and monitored + * resource. + * <pre> {@code + * String logName = "my_log_name"; + * List<LogEntry> entries = new ArrayList<>(); + * entries.add(LogEntry.of(StringPayload.of("Entry payload"))); + * Map<String, Object> jsonMap = new HashMap<>(); + * jsonMap.put("key", "value"); + * entries.add(LogEntry.of(JsonPayload.of(jsonMap))); + * Future<Void> future = logging.writeAsync( + * entries, + * WriteOption.logName(logName), + * WriteOption.resource(MonitoredResource.builder("global").build())); + * }</pre> + * */ Future<Void> writeAsync(Iterable<LogEntry> logEntries, WriteOption... options); @@ -402,6 +702,17 @@ Future<AsyncPage<MonitoredResourceDescriptor>> listMonitoredResourceDescriptorsA * according to your preferred order (default is most-recent last). Use * {@link EntryListOption#filter(String)} to filter listed log entries. * + * <p>Example of listing log entries for a specific log. + * <pre> {@code + * String filter = "logName=projects/my_project_id/logs/my_log_name"; + * Page<LogEntry> entries = logging.listLogEntries(EntryListOption.filter(filter)); + * Iterator<LogEntry> entryIterator = entries.iterateAll(); + * while (entryIterator.hasNext()) { + * LogEntry entry = entryIterator.next(); + * // do something with the entry + * } + * }</pre> + * * @throws LoggingException upon failure */ Page<LogEntry> listLogEntries(EntryListOption... options); @@ -416,6 +727,20 @@ Future<AsyncPage<MonitoredResourceDescriptor>> listMonitoredResourceDescriptorsA * your preferred order (default is most-recent last). Use {@link EntryListOption#filter(String)} * to filter listed log entries. * + * <p>Example of asynchronously listing log entries for a specific log. + * <pre> {@code + * String filter = "logName=projects/my_project_id/logs/my_log_name"; + * Future<AsyncPage<LogEntry>> future = + * logging.listLogEntriesAsync(EntryListOption.filter(filter)); + * // ... + * AsyncPage<LogEntry> entries = future.get(); + * Iterator<LogEntry> entryIterator = entries.iterateAll(); + * while (entryIterator.hasNext()) { + * LogEntry entry = entryIterator.next(); + * // do something with the entry + * } + * }</pre> + * * @throws LoggingException upon failure */ Future<AsyncPage<LogEntry>> listLogEntriesAsync(EntryListOption... options);