diff --git a/.github/.OwlBot.lock.yaml b/.github/.OwlBot.lock.yaml
index a79f06271..68f2b159d 100644
--- a/.github/.OwlBot.lock.yaml
+++ b/.github/.OwlBot.lock.yaml
@@ -13,5 +13,5 @@
# limitations under the License.
docker:
image: gcr.io/cloud-devrel-public-resources/owlbot-java:latest
- digest: sha256:2567a120ce90fadb6201999b87d649d9f67459de28815ad239bce9ebfaa18a74
-# created: 2022-05-19T15:12:45.278246753Z
+ digest: sha256:58ccd4737212f64a7dd4b3063d447447acf71a2b9d409eab19fc7a00b18eadc0
+# created: 2022-06-10T19:20:11.004014696Z
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a6f324103..96fc9d96d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,23 @@
# Changelog
+## [3.10.0](https://github.com/googleapis/java-logging/compare/v3.9.0...v3.10.0) (2022-06-25)
+
+
+### Features
+
+* Add support for library instrumentation ([#979](https://github.com/googleapis/java-logging/issues/979)) ([2749974](https://github.com/googleapis/java-logging/commit/27499744f37a5fddcc2d6825c69481374e78829c))
+
+
+### Documentation
+
+* **sample:** update README for native image sample ([#974](https://github.com/googleapis/java-logging/issues/974)) ([1512487](https://github.com/googleapis/java-logging/commit/1512487e60141ed5c61a3a60fcca29f52f4ec141))
+
+
+### Dependencies
+
+* update dependency com.google.cloud:google-cloud-shared-dependencies to v2.13.0 ([#980](https://github.com/googleapis/java-logging/issues/980)) ([18acf1f](https://github.com/googleapis/java-logging/commit/18acf1f64d836ca3fb1b8f4b558ef21d728c391f))
+* update dependency org.graalvm.buildtools:junit-platform-native to v0.9.12 ([#976](https://github.com/googleapis/java-logging/issues/976)) ([01d3213](https://github.com/googleapis/java-logging/commit/01d3213b9e010c3ae3843e5a05bbd01b2961b454))
+
## [3.9.0](https://github.com/googleapis/java-logging/compare/v3.8.0...v3.9.0) (2022-05-19)
diff --git a/README.md b/README.md
index 45f7872c3..46021884c 100644
--- a/README.md
+++ b/README.md
@@ -19,7 +19,7 @@ If you are using Maven with [BOM][libraries-bom], add this to your pom.xml file
com.google.cloud
libraries-bom
- 25.3.0
+ 25.4.0
pom
import
@@ -43,7 +43,7 @@ If you are using Maven without BOM, add this to your dependencies:
com.google.cloud
google-cloud-logging
- 3.7.6
+ 3.8.0
```
@@ -51,20 +51,20 @@ If you are using Maven without BOM, add this to your dependencies:
If you are using Gradle 5.x or later, add this to your dependencies
```Groovy
-implementation platform('com.google.cloud:libraries-bom:25.3.0')
+implementation platform('com.google.cloud:libraries-bom:25.4.0')
implementation 'com.google.cloud:google-cloud-logging'
```
If you are using Gradle without BOM, add this to your dependencies
```Groovy
-implementation 'com.google.cloud:google-cloud-logging:3.8.0'
+implementation 'com.google.cloud:google-cloud-logging:3.9.0'
```
If you are using SBT, add this to your dependencies
```Scala
-libraryDependencies += "com.google.cloud" % "google-cloud-logging" % "3.8.0"
+libraryDependencies += "com.google.cloud" % "google-cloud-logging" % "3.9.0"
```
## Authentication
diff --git a/google-cloud-logging-bom/pom.xml b/google-cloud-logging-bom/pom.xml
index d88d9de74..af6ba5253 100644
--- a/google-cloud-logging-bom/pom.xml
+++ b/google-cloud-logging-bom/pom.xml
@@ -3,12 +3,12 @@
4.0.0
com.google.cloud
google-cloud-logging-bom
- 3.9.0
+ 3.10.0
pom
com.google.cloud
google-cloud-shared-config
- 1.4.0
+ 1.5.0
Google Cloud logging BOM
@@ -53,17 +53,17 @@
com.google.cloud
google-cloud-logging
- 3.9.0
+ 3.10.0
com.google.api.grpc
grpc-google-cloud-logging-v2
- 0.98.0
+ 0.99.0
com.google.api.grpc
proto-google-cloud-logging-v2
- 0.98.0
+ 0.99.0
diff --git a/google-cloud-logging/pom.xml b/google-cloud-logging/pom.xml
index b4fa79a91..223f5f1fd 100644
--- a/google-cloud-logging/pom.xml
+++ b/google-cloud-logging/pom.xml
@@ -3,7 +3,7 @@
4.0.0
com.google.cloud
google-cloud-logging
- 3.9.0
+ 3.10.0
jar
Google Cloud Logging
https://github.com/googleapis/java-logging
@@ -11,7 +11,7 @@
com.google.cloud
google-cloud-logging-parent
- 3.9.0
+ 3.10.0
google-cloud-logging
diff --git a/google-cloud-logging/src/main/java/com/google/cloud/logging/Instrumentation.java b/google-cloud-logging/src/main/java/com/google/cloud/logging/Instrumentation.java
new file mode 100644
index 000000000..8471d882e
--- /dev/null
+++ b/google-cloud-logging/src/main/java/com/google/cloud/logging/Instrumentation.java
@@ -0,0 +1,224 @@
+/*
+ * Copyright 2022 Google LLC
+ *
+ * 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.logging;
+
+import com.google.api.client.util.Strings;
+import com.google.api.gax.core.GaxProperties;
+import com.google.cloud.Tuple;
+import com.google.cloud.logging.Logging.WriteOption;
+import com.google.cloud.logging.Payload.JsonPayload;
+import com.google.cloud.logging.Payload.Type;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
+import com.google.protobuf.ListValue;
+import com.google.protobuf.Struct;
+import com.google.protobuf.Value;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class Instrumentation {
+ public static final String DIAGNOSTIC_INFO_KEY = "logging.googleapis.com/diagnostic";
+ public static final String INSTRUMENTATION_SOURCE_KEY = "instrumentation_source";
+ public static final String INSTRUMENTATION_NAME_KEY = "name";
+ public static final String INSTRUMENTATION_VERSION_KEY = "version";
+ public static final String JAVA_LIBRARY_NAME_PREFIX = "java";
+ public static final String DEFAULT_INSTRUMENTATION_VERSION = "UNKNOWN";
+ public static final String INSTRUMENTATION_LOG_NAME = "diagnostic-log";
+ public static final int MAX_DIAGNOSTIC_VALUE_LENGTH = 14;
+ public static final int MAX_DIAGNOSTIC_ENTIES = 3;
+ private static boolean instrumentationAdded = false;
+ private static Object instrumentationLock = new Object();
+
+ /**
+ * Populates entries with instrumentation info which is added in separate log entry
+ *
+ * @param logEntries {Iterable} The list of entries to be populated
+ * @return {Tuple>} containg a flag if instrumentation info was added
+ * or not and a modified list of log entries
+ */
+ public static Tuple> populateInstrumentationInfo(
+ Iterable logEntries) {
+ boolean isWritten = setInstrumentationStatus(true);
+ if (isWritten) return Tuple.of(false, logEntries);
+ List entries = new ArrayList<>();
+
+ for (LogEntry logEntry : logEntries) {
+ // Check if LogEntry has a proper payload and also contains a diagnostic entry
+ if (!isWritten
+ && logEntry.getPayload().getType() == Type.JSON
+ && logEntry
+ .getPayload()
+ .getData()
+ .containsFields(DIAGNOSTIC_INFO_KEY)) {
+ try {
+ ListValue infoList =
+ logEntry
+ .getPayload()
+ .getData()
+ .getFieldsOrThrow(DIAGNOSTIC_INFO_KEY)
+ .getStructValue()
+ .getFieldsOrThrow(INSTRUMENTATION_SOURCE_KEY)
+ .getListValue();
+ entries.add(createDiagnosticEntry(null, null, infoList));
+ isWritten = true;
+ } catch (Exception ex) {
+ System.err.println("ERROR: unexpected exception in populateInstrumentationInfo: " + ex);
+ }
+ } else {
+ entries.add(logEntry);
+ }
+ }
+ if (!isWritten) {
+ entries.add(createDiagnosticEntry(null, null, null));
+ }
+ return Tuple.of(true, entries);
+ }
+
+ /**
+ * Adds a partialSuccess flag option to array of WriteOption
+ *
+ * @param options {WriteOption[]} The options array to be extended
+ * @return The new array of oprions containing WriteOption.OptionType.PARTIAL_SUCCESS flag set to
+ * true
+ */
+ public static WriteOption[] addPartialSuccessOption(WriteOption[] options) {
+ if (options == null) return options;
+ List writeOptions = new ArrayList();
+ writeOptions.addAll(Arrays.asList(options));
+ // Make sure we remove all partial success flags if any exist
+ writeOptions.removeIf(
+ option -> option.getOptionType() == WriteOption.OptionType.PARTIAL_SUCCESS);
+ writeOptions.add(WriteOption.partialSuccess(true));
+ return Iterables.toArray(writeOptions, WriteOption.class);
+ }
+
+ /**
+ * The helper method to generate a log entry with diagnostic instrumentation data.
+ *
+ * @param libraryName {string} The name of the logging library to be reported. Should be prefixed
+ * with 'java'. Will be truncated if longer than 14 characters.
+ * @param libraryVersion {string} The version of the logging library to be reported. Will be
+ * truncated if longer than 14 characters.
+ * @returns {LogEntry} The entry with diagnostic instrumentation data.
+ */
+ public static LogEntry createDiagnosticEntry(String libraryName, String libraryVersion) {
+ return createDiagnosticEntry(libraryName, libraryVersion, null);
+ }
+
+ private static LogEntry createDiagnosticEntry(
+ String libraryName, String libraryVersion, ListValue existingLibraryList) {
+ Struct instrumentation =
+ Struct.newBuilder()
+ .putAllFields(
+ ImmutableMap.of(
+ INSTRUMENTATION_SOURCE_KEY,
+ Value.newBuilder()
+ .setListValue(
+ generateLibrariesList(libraryName, libraryVersion, existingLibraryList))
+ .build()))
+ .build();
+ LogEntry entry =
+ LogEntry.newBuilder(
+ JsonPayload.of(
+ Struct.newBuilder()
+ .putAllFields(
+ ImmutableMap.of(
+ DIAGNOSTIC_INFO_KEY,
+ Value.newBuilder().setStructValue(instrumentation).build()))
+ .build()))
+ .setLogName(INSTRUMENTATION_LOG_NAME)
+ .build();
+ return entry;
+ }
+
+ private static ListValue generateLibrariesList(
+ String libraryName, String libraryVersion, ListValue existingLibraryList) {
+ if (Strings.isNullOrEmpty(libraryName) || !libraryName.startsWith(JAVA_LIBRARY_NAME_PREFIX))
+ libraryName = JAVA_LIBRARY_NAME_PREFIX;
+ if (Strings.isNullOrEmpty(libraryVersion)) {
+ libraryVersion = getLibraryVersion(Instrumentation.class.getClass());
+ }
+ Struct libraryInfo = createInfoStruct(libraryName, libraryVersion);
+ ListValue.Builder libraryList = ListValue.newBuilder();
+ // Append first the library info for this library
+ libraryList.addValues(Value.newBuilder().setStructValue(libraryInfo).build());
+ if (existingLibraryList != null) {
+ for (Value val : existingLibraryList.getValuesList()) {
+ if (val.hasStructValue()) {
+ try {
+ String name =
+ val.getStructValue().getFieldsOrThrow(INSTRUMENTATION_NAME_KEY).getStringValue();
+ if (Strings.isNullOrEmpty(name) || !name.startsWith(JAVA_LIBRARY_NAME_PREFIX)) continue;
+ String version =
+ val.getStructValue().getFieldsOrThrow(INSTRUMENTATION_VERSION_KEY).getStringValue();
+ if (Strings.isNullOrEmpty(version)) continue;
+ libraryList.addValues(
+ Value.newBuilder().setStructValue(createInfoStruct(name, version)).build());
+ if (libraryList.getValuesCount() == MAX_DIAGNOSTIC_ENTIES) break;
+ } catch (Exception ex) {
+ }
+ }
+ }
+ }
+ return libraryList.build();
+ }
+
+ private static Struct createInfoStruct(String libraryName, String libraryVersion) {
+ return Struct.newBuilder()
+ .putAllFields(
+ ImmutableMap.of(
+ INSTRUMENTATION_NAME_KEY,
+ Value.newBuilder().setStringValue(truncateValue(libraryName)).build(),
+ INSTRUMENTATION_VERSION_KEY,
+ Value.newBuilder().setStringValue(truncateValue(libraryVersion)).build()))
+ .build();
+ }
+
+ /**
+ * The package-private helper method used to set the flag which indicates if instrumentation info
+ * already written or not.
+ *
+ * @returns The value of the flag before it was set.
+ */
+ static boolean setInstrumentationStatus(boolean value) {
+ if (instrumentationAdded == value) return instrumentationAdded;
+ synchronized (instrumentationLock) {
+ boolean current = instrumentationAdded;
+ instrumentationAdded = value;
+ return current;
+ }
+ }
+
+ /**
+ * Returns a library version associated with given class
+ *
+ * @param libraryClass {Class>} The class to be used to determine a library version
+ * @return The version number string for given class or "UNKNOWN" if class library version cannot
+ * be detected
+ */
+ public static String getLibraryVersion(Class> libraryClass) {
+ String libraryVersion = GaxProperties.getLibraryVersion(libraryClass);
+ if (Strings.isNullOrEmpty(libraryVersion)) libraryVersion = DEFAULT_INSTRUMENTATION_VERSION;
+ return libraryVersion;
+ }
+
+ private static String truncateValue(String value) {
+ if (Strings.isNullOrEmpty(value) || value.length() < MAX_DIAGNOSTIC_VALUE_LENGTH) return value;
+ return value.substring(0, MAX_DIAGNOSTIC_VALUE_LENGTH) + "*";
+ }
+}
diff --git a/google-cloud-logging/src/main/java/com/google/cloud/logging/Logging.java b/google-cloud-logging/src/main/java/com/google/cloud/logging/Logging.java
index a765c73e0..832c61137 100644
--- a/google-cloud-logging/src/main/java/com/google/cloud/logging/Logging.java
+++ b/google-cloud-logging/src/main/java/com/google/cloud/logging/Logging.java
@@ -71,7 +71,8 @@ enum OptionType implements Option.OptionType {
RESOURCE,
LABELS,
LOG_DESTINATION,
- AUTO_POPULATE_METADATA;
+ AUTO_POPULATE_METADATA,
+ PARTIAL_SUCCESS;
@SuppressWarnings("unchecked")
T get(Map options) {
@@ -123,6 +124,15 @@ public static WriteOption destination(LogDestinationName destination) {
public static WriteOption autoPopulateMetadata(boolean autoPopulateMetadata) {
return new WriteOption(OptionType.AUTO_POPULATE_METADATA, autoPopulateMetadata);
}
+
+ /**
+ * Returns an option to set partialSuccess flag. See {@link
+ * https://cloud.google.com/logging/docs/reference/v2/rest/v2/entries/write#body.request_body.FIELDS.partial_success}
+ * for more details.
+ */
+ public static WriteOption partialSuccess(boolean partialSuccess) {
+ return new WriteOption(OptionType.PARTIAL_SUCCESS, partialSuccess);
+ }
}
/** Fields according to which log entries can be sorted. */
diff --git a/google-cloud-logging/src/main/java/com/google/cloud/logging/LoggingHandler.java b/google-cloud-logging/src/main/java/com/google/cloud/logging/LoggingHandler.java
index 92b9f8794..ffa4c6273 100644
--- a/google-cloud-logging/src/main/java/com/google/cloud/logging/LoggingHandler.java
+++ b/google-cloud-logging/src/main/java/com/google/cloud/logging/LoggingHandler.java
@@ -312,7 +312,10 @@ public void publish(LogRecord record) {
}
if (logEntry != null) {
try {
- Iterable logEntries = ImmutableList.of(logEntry);
+ Iterable logEntries =
+ redirectToStdout
+ ? Instrumentation.populateInstrumentationInfo(ImmutableList.of(logEntry)).y()
+ : ImmutableList.of(logEntry);
if (autoPopulateMetadata) {
logEntries =
logging.populateMetadata(
diff --git a/google-cloud-logging/src/main/java/com/google/cloud/logging/LoggingImpl.java b/google-cloud-logging/src/main/java/com/google/cloud/logging/LoggingImpl.java
index c75658c11..a2078e079 100644
--- a/google-cloud-logging/src/main/java/com/google/cloud/logging/LoggingImpl.java
+++ b/google-cloud-logging/src/main/java/com/google/cloud/logging/LoggingImpl.java
@@ -23,6 +23,7 @@
import static com.google.cloud.logging.Logging.WriteOption.OptionType.LABELS;
import static com.google.cloud.logging.Logging.WriteOption.OptionType.LOG_DESTINATION;
import static com.google.cloud.logging.Logging.WriteOption.OptionType.LOG_NAME;
+import static com.google.cloud.logging.Logging.WriteOption.OptionType.PARTIAL_SUCCESS;
import static com.google.cloud.logging.Logging.WriteOption.OptionType.RESOURCE;
import static com.google.common.base.Preconditions.checkNotNull;
@@ -39,6 +40,7 @@
import com.google.cloud.MonitoredResource;
import com.google.cloud.MonitoredResourceDescriptor;
import com.google.cloud.PageImpl;
+import com.google.cloud.Tuple;
import com.google.cloud.logging.spi.v2.LoggingRpc;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
@@ -92,7 +94,6 @@
import java.util.concurrent.TimeoutException;
class LoggingImpl extends BaseService implements Logging {
-
protected static final String RESOURCE_NAME_FORMAT = "projects/%s/traces/%s";
private static final int FLUSH_WAIT_TIMEOUT_SECONDS = 6;
private final LoggingRpc rpc;
@@ -774,6 +775,7 @@ private static WriteLogEntriesRequest writeLogEntriesRequest(
builder.putAllLabels(labels);
}
+ builder.setPartialSuccess(Boolean.TRUE.equals(PARTIAL_SUCCESS.get(options)));
builder.addAllEntries(Iterables.transform(logEntries, LogEntry.toPbFunction(projectId)));
return builder.build();
}
@@ -851,6 +853,9 @@ public void write(Iterable logEntries, WriteOption... options) {
final Boolean logingOptionsPopulateFlag = getOptions().getAutoPopulateMetadata();
final Boolean writeOptionPopulateFlga =
WriteOption.OptionType.AUTO_POPULATE_METADATA.get(writeOptions);
+ Tuple> pair =
+ Instrumentation.populateInstrumentationInfo(logEntries);
+ logEntries = pair.y();
if (writeOptionPopulateFlga == Boolean.TRUE
|| (writeOptionPopulateFlga == null && logingOptionsPopulateFlag == Boolean.TRUE)) {
@@ -858,8 +863,9 @@ public void write(Iterable logEntries, WriteOption... options) {
logEntries =
populateMetadata(logEntries, sharedResourceMetadata, this.getClass().getName());
}
-
- writeLogEntries(logEntries, options);
+ // Add partialSuccess option always for request containing instrumentation data
+ writeLogEntries(
+ logEntries, pair.x() ? Instrumentation.addPartialSuccessOption(options) : options);
if (flushSeverity != null) {
for (LogEntry logEntry : logEntries) {
// flush pending writes if log severity at or above flush severity
diff --git a/google-cloud-logging/src/main/java/com/google/cloud/logging/v2/ConfigClient.java b/google-cloud-logging/src/main/java/com/google/cloud/logging/v2/ConfigClient.java
index dc686eafe..e038117dc 100644
--- a/google-cloud-logging/src/main/java/com/google/cloud/logging/v2/ConfigClient.java
+++ b/google-cloud-logging/src/main/java/com/google/cloud/logging/v2/ConfigClient.java
@@ -18,7 +18,6 @@
import com.google.api.core.ApiFuture;
import com.google.api.core.ApiFutures;
-import com.google.api.core.BetaApi;
import com.google.api.gax.core.BackgroundResource;
import com.google.api.gax.longrunning.OperationFuture;
import com.google.api.gax.paging.AbstractFixedSizeCollection;
@@ -181,7 +180,6 @@ public static final ConfigClient create(ConfigSettings settings) throws IOExcept
* Constructs an instance of ConfigClient, using the given stub for making calls. This is for
* advanced usage - prefer using create(ConfigSettings).
*/
- @BetaApi("A restructuring of stub classes is planned, so this may break in the future")
public static final ConfigClient create(ConfigServiceV2Stub stub) {
return new ConfigClient(stub);
}
@@ -196,7 +194,6 @@ protected ConfigClient(ConfigSettings settings) throws IOException {
this.operationsClient = OperationsClient.create(this.stub.getOperationsStub());
}
- @BetaApi("A restructuring of stub classes is planned, so this may break in the future")
protected ConfigClient(ConfigServiceV2Stub stub) {
this.settings = null;
this.stub = stub;
@@ -207,7 +204,6 @@ public final ConfigSettings getSettings() {
return settings;
}
- @BetaApi("A restructuring of stub classes is planned, so this may break in the future")
public ConfigServiceV2Stub getStub() {
return stub;
}
@@ -464,7 +460,7 @@ public final ListBucketsPagedResponse listBuckets(ListBucketsRequest request) {
* .build();
* while (true) {
* ListBucketsResponse response = configClient.listBucketsCallable().call(request);
- * for (LogBucket element : response.getResponsesList()) {
+ * for (LogBucket element : response.getBucketsList()) {
* // doThingsWith(element);
* }
* String nextPageToken = response.getNextPageToken();
@@ -879,7 +875,7 @@ public final UnaryCallable listViewsPa
* .build();
* while (true) {
* ListViewsResponse response = configClient.listViewsCallable().call(request);
- * for (LogView element : response.getResponsesList()) {
+ * for (LogView element : response.getViewsList()) {
* // doThingsWith(element);
* }
* String nextPageToken = response.getNextPageToken();
@@ -1336,7 +1332,7 @@ public final UnaryCallable listSinksPa
* .build();
* while (true) {
* ListSinksResponse response = configClient.listSinksCallable().call(request);
- * for (LogSink element : response.getResponsesList()) {
+ * for (LogSink element : response.getSinksList()) {
* // doThingsWith(element);
* }
* String nextPageToken = response.getNextPageToken();
@@ -2294,7 +2290,7 @@ public final ListExclusionsPagedResponse listExclusions(ListExclusionsRequest re
* .build();
* while (true) {
* ListExclusionsResponse response = configClient.listExclusionsCallable().call(request);
- * for (LogExclusion element : response.getResponsesList()) {
+ * for (LogExclusion element : response.getExclusionsList()) {
* // doThingsWith(element);
* }
* String nextPageToken = response.getNextPageToken();
diff --git a/google-cloud-logging/src/main/java/com/google/cloud/logging/v2/LoggingClient.java b/google-cloud-logging/src/main/java/com/google/cloud/logging/v2/LoggingClient.java
index 92f83bed0..a80f2f0bd 100644
--- a/google-cloud-logging/src/main/java/com/google/cloud/logging/v2/LoggingClient.java
+++ b/google-cloud-logging/src/main/java/com/google/cloud/logging/v2/LoggingClient.java
@@ -20,7 +20,6 @@
import com.google.api.MonitoredResourceDescriptor;
import com.google.api.core.ApiFuture;
import com.google.api.core.ApiFutures;
-import com.google.api.core.BetaApi;
import com.google.api.gax.core.BackgroundResource;
import com.google.api.gax.paging.AbstractFixedSizeCollection;
import com.google.api.gax.paging.AbstractPage;
@@ -142,7 +141,6 @@ public static final LoggingClient create(LoggingSettings settings) throws IOExce
* Constructs an instance of LoggingClient, using the given stub for making calls. This is for
* advanced usage - prefer using create(LoggingSettings).
*/
- @BetaApi("A restructuring of stub classes is planned, so this may break in the future")
public static final LoggingClient create(LoggingServiceV2Stub stub) {
return new LoggingClient(stub);
}
@@ -156,7 +154,6 @@ protected LoggingClient(LoggingSettings settings) throws IOException {
this.stub = ((LoggingServiceV2StubSettings) settings.getStubSettings()).createStub();
}
- @BetaApi("A restructuring of stub classes is planned, so this may break in the future")
protected LoggingClient(LoggingServiceV2Stub stub) {
this.settings = null;
this.stub = stub;
@@ -166,7 +163,6 @@ public final LoggingSettings getSettings() {
return settings;
}
- @BetaApi("A restructuring of stub classes is planned, so this may break in the future")
public LoggingServiceV2Stub getStub() {
return stub;
}
@@ -678,7 +674,7 @@ public final ListLogEntriesPagedResponse listLogEntries(ListLogEntriesRequest re
* .build();
* while (true) {
* ListLogEntriesResponse response = loggingClient.listLogEntriesCallable().call(request);
- * for (LogEntry element : response.getResponsesList()) {
+ * for (LogEntry element : response.getEntriesList()) {
* // doThingsWith(element);
* }
* String nextPageToken = response.getNextPageToken();
@@ -774,7 +770,7 @@ public final ListMonitoredResourceDescriptorsPagedResponse listMonitoredResource
* while (true) {
* ListMonitoredResourceDescriptorsResponse response =
* loggingClient.listMonitoredResourceDescriptorsCallable().call(request);
- * for (MonitoredResourceDescriptor element : response.getResponsesList()) {
+ * for (MonitoredResourceDescriptor element : response.getResourceDescriptorsList()) {
* // doThingsWith(element);
* }
* String nextPageToken = response.getNextPageToken();
@@ -1043,7 +1039,7 @@ public final UnaryCallable listLogsPaged
* .build();
* while (true) {
* ListLogsResponse response = loggingClient.listLogsCallable().call(request);
- * for (String element : response.getResponsesList()) {
+ * for (String element : response.getLogNamesList()) {
* // doThingsWith(element);
* }
* String nextPageToken = response.getNextPageToken();
diff --git a/google-cloud-logging/src/main/java/com/google/cloud/logging/v2/MetricsClient.java b/google-cloud-logging/src/main/java/com/google/cloud/logging/v2/MetricsClient.java
index c74e0a912..3f1565fc5 100644
--- a/google-cloud-logging/src/main/java/com/google/cloud/logging/v2/MetricsClient.java
+++ b/google-cloud-logging/src/main/java/com/google/cloud/logging/v2/MetricsClient.java
@@ -18,7 +18,6 @@
import com.google.api.core.ApiFuture;
import com.google.api.core.ApiFutures;
-import com.google.api.core.BetaApi;
import com.google.api.gax.core.BackgroundResource;
import com.google.api.gax.paging.AbstractFixedSizeCollection;
import com.google.api.gax.paging.AbstractPage;
@@ -130,7 +129,6 @@ public static final MetricsClient create(MetricsSettings settings) throws IOExce
* Constructs an instance of MetricsClient, using the given stub for making calls. This is for
* advanced usage - prefer using create(MetricsSettings).
*/
- @BetaApi("A restructuring of stub classes is planned, so this may break in the future")
public static final MetricsClient create(MetricsServiceV2Stub stub) {
return new MetricsClient(stub);
}
@@ -144,7 +142,6 @@ protected MetricsClient(MetricsSettings settings) throws IOException {
this.stub = ((MetricsServiceV2StubSettings) settings.getStubSettings()).createStub();
}
- @BetaApi("A restructuring of stub classes is planned, so this may break in the future")
protected MetricsClient(MetricsServiceV2Stub stub) {
this.settings = null;
this.stub = stub;
@@ -154,7 +151,6 @@ public final MetricsSettings getSettings() {
return settings;
}
- @BetaApi("A restructuring of stub classes is planned, so this may break in the future")
public MetricsServiceV2Stub getStub() {
return stub;
}
@@ -290,7 +286,7 @@ public final ListLogMetricsPagedResponse listLogMetrics(ListLogMetricsRequest re
* .build();
* while (true) {
* ListLogMetricsResponse response = metricsClient.listLogMetricsCallable().call(request);
- * for (LogMetric element : response.getResponsesList()) {
+ * for (LogMetric element : response.getMetricsList()) {
* // doThingsWith(element);
* }
* String nextPageToken = response.getNextPageToken();
diff --git a/google-cloud-logging/src/main/java/com/google/cloud/logging/v2/stub/ConfigServiceV2StubSettings.java b/google-cloud-logging/src/main/java/com/google/cloud/logging/v2/stub/ConfigServiceV2StubSettings.java
index 0ee548e17..55030892f 100644
--- a/google-cloud-logging/src/main/java/com/google/cloud/logging/v2/stub/ConfigServiceV2StubSettings.java
+++ b/google-cloud-logging/src/main/java/com/google/cloud/logging/v2/stub/ConfigServiceV2StubSettings.java
@@ -533,7 +533,6 @@ public UnaryCallSettings copyLogEntriesSetting
return copyLogEntriesOperationSettings;
}
- @BetaApi("A restructuring of stub classes is planned, so this may break in the future")
public ConfigServiceV2Stub createStub() throws IOException {
if (getTransportChannelProvider()
.getTransportName()
diff --git a/google-cloud-logging/src/main/java/com/google/cloud/logging/v2/stub/LoggingServiceV2StubSettings.java b/google-cloud-logging/src/main/java/com/google/cloud/logging/v2/stub/LoggingServiceV2StubSettings.java
index 180ef48c6..220b7f22c 100644
--- a/google-cloud-logging/src/main/java/com/google/cloud/logging/v2/stub/LoggingServiceV2StubSettings.java
+++ b/google-cloud-logging/src/main/java/com/google/cloud/logging/v2/stub/LoggingServiceV2StubSettings.java
@@ -424,7 +424,6 @@ public UnaryCallSettings deleteLogSettings() {
return tailLogEntriesSettings;
}
- @BetaApi("A restructuring of stub classes is planned, so this may break in the future")
public LoggingServiceV2Stub createStub() throws IOException {
if (getTransportChannelProvider()
.getTransportName()
diff --git a/google-cloud-logging/src/main/java/com/google/cloud/logging/v2/stub/MetricsServiceV2StubSettings.java b/google-cloud-logging/src/main/java/com/google/cloud/logging/v2/stub/MetricsServiceV2StubSettings.java
index 5716cdcea..871b9b1ee 100644
--- a/google-cloud-logging/src/main/java/com/google/cloud/logging/v2/stub/MetricsServiceV2StubSettings.java
+++ b/google-cloud-logging/src/main/java/com/google/cloud/logging/v2/stub/MetricsServiceV2StubSettings.java
@@ -192,7 +192,6 @@ public UnaryCallSettings deleteLogMetricSettings(
return deleteLogMetricSettings;
}
- @BetaApi("A restructuring of stub classes is planned, so this may break in the future")
public MetricsServiceV2Stub createStub() throws IOException {
if (getTransportChannelProvider()
.getTransportName()
diff --git a/google-cloud-logging/src/test/java/com/google/cloud/logging/InstrumentationTest.java b/google-cloud-logging/src/test/java/com/google/cloud/logging/InstrumentationTest.java
new file mode 100644
index 000000000..5838fa80f
--- /dev/null
+++ b/google-cloud-logging/src/test/java/com/google/cloud/logging/InstrumentationTest.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright 2022 Google LLC
+ *
+ * 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.logging;
+
+import com.google.api.client.util.Lists;
+import com.google.cloud.Tuple;
+import com.google.cloud.logging.Payload.JsonPayload;
+import com.google.cloud.logging.Payload.StringPayload;
+import com.google.cloud.logging.Payload.Type;
+import com.google.common.collect.ImmutableList;
+import com.google.protobuf.ListValue;
+import com.google.protobuf.Value;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class InstrumentationTest {
+ private static final StringPayload STRING_PAYLOAD = StringPayload.of("payload");
+ private static final LogEntry STRING_ENTRY = LogEntry.newBuilder(STRING_PAYLOAD).build();
+ private static final String JAVA_OTHER_NAME = "java-other";
+ private static final String JAVA_INVALID_NAME = "no-java-name";
+ private static final String JAVA_OTHER_VERSION = "1.0.0";
+
+ @Test
+ public void testInstrumentationGenerated() {
+ Instrumentation.setInstrumentationStatus(false);
+ verifyEntries(
+ Instrumentation.populateInstrumentationInfo(ImmutableList.of(STRING_ENTRY)),
+ 1,
+ 2,
+ new HashSet<>(Arrays.asList(Instrumentation.JAVA_LIBRARY_NAME_PREFIX)),
+ new HashSet<>(
+ Arrays.asList(Instrumentation.getLibraryVersion(Instrumentation.class.getClass()))));
+ }
+
+ @Test
+ public void testNoInstrumentationGenerated() {
+ Instrumentation.setInstrumentationStatus(true);
+ Tuple> pair =
+ Instrumentation.populateInstrumentationInfo(ImmutableList.of(STRING_ENTRY));
+ ArrayList entries = Lists.newArrayList(pair.y());
+ Assert.assertFalse(pair.x());
+ Assert.assertEquals(entries.size(), 1);
+ Assert.assertTrue(entries.get(0).getPayload().getType() == Type.STRING);
+ }
+
+ @Test
+ public void testInstrumentationUpdated() {
+ Instrumentation.setInstrumentationStatus(false);
+ LogEntry json_entry =
+ LogEntry.newBuilder(generateInstrumentationPayload(JAVA_OTHER_NAME, JAVA_OTHER_VERSION))
+ .build();
+ verifyEntries(
+ Instrumentation.populateInstrumentationInfo(ImmutableList.of(json_entry)),
+ 0,
+ 1,
+ new HashSet<>(Arrays.asList(Instrumentation.JAVA_LIBRARY_NAME_PREFIX, JAVA_OTHER_NAME)),
+ new HashSet<>(
+ Arrays.asList(
+ Instrumentation.getLibraryVersion(Instrumentation.class.getClass()),
+ JAVA_OTHER_VERSION)));
+ }
+
+ @Test
+ public void testInvalidInstrumentationRemoved() {
+ Instrumentation.setInstrumentationStatus(false);
+ LogEntry json_entry =
+ LogEntry.newBuilder(generateInstrumentationPayload(JAVA_INVALID_NAME, JAVA_OTHER_VERSION))
+ .build();
+ verifyEntries(
+ Instrumentation.populateInstrumentationInfo(ImmutableList.of(json_entry)),
+ 0,
+ 1,
+ new HashSet<>(Arrays.asList(Instrumentation.JAVA_LIBRARY_NAME_PREFIX)),
+ new HashSet<>(
+ Arrays.asList(Instrumentation.getLibraryVersion(Instrumentation.class.getClass()))));
+ }
+
+ public static JsonPayload generateInstrumentationPayload(
+ String libraryName, String libraryVersion) {
+ Map json_data = new HashMap<>();
+ Map instrumentation_data = new HashMap<>();
+ Map info = new HashMap<>();
+ info.put(Instrumentation.INSTRUMENTATION_NAME_KEY, libraryName);
+ info.put(Instrumentation.INSTRUMENTATION_VERSION_KEY, libraryVersion);
+ List