Skip to content

Commit 944f366

Browse files
authored
Merge pull request #1122 from mziccard/add-logging-support
Add support for Stackdriver Logging
2 parents 05795ca + 1842375 commit 944f366

79 files changed

Lines changed: 19449 additions & 4 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ This client supports the following Google Cloud Platform services:
1818
- [Google Cloud Compute] (#google-cloud-compute-alpha) (Alpha)
1919
- [Google Cloud Datastore] (#google-cloud-datastore)
2020
- [Google Cloud DNS] (#google-cloud-dns-alpha) (Alpha)
21+
- [Stackdriver Logging] (#stackdriver-logging-alpha) (Alpha - Not working on App Engine Standard)
2122
- [Google Cloud Pub/Sub] (#google-cloud-pubsub-alpha) (Alpha - Not working on App Engine Standard)
2223
- [Google Cloud Resource Manager] (#google-cloud-resource-manager-alpha) (Alpha)
2324
- [Google Cloud Storage] (#google-cloud-storage)
@@ -371,6 +372,75 @@ ChangeRequestInfo changeRequest = changeBuilder.build();
371372
zone.applyChangeRequest(changeRequest);
372373
```
373374
375+
Stackdriver Logging (Alpha)
376+
----------------------
377+
- [API Documentation][logging-api]
378+
- [Official Documentation][stackdriver-logging-docs]
379+
380+
*Follow the [activation instructions][stackdriver-logging-activation] to use the Stackdriver Logging
381+
API with your project.*
382+
383+
#### Preview
384+
385+
Here are two code snippets showing simple usage examples from within Compute Engine/App Engine
386+
Flexible. Note that you must [supply credentials](#authentication) and a project ID if running this
387+
snippet elsewhere.
388+
389+
The first snippet shows how to write and list log entries. Complete source code can be found on
390+
[WriteAndListLogEntries.java](./gcloud-java-examples/src/main/java/com/google/cloud/examples/logging/snippets/WriteAndListLogEntries.java).
391+
392+
```java
393+
import com.google.cloud.MonitoredResource;
394+
import com.google.cloud.Page;
395+
import com.google.cloud.logging.LogEntry;
396+
import com.google.cloud.logging.Logging;
397+
import com.google.cloud.logging.Logging.EntryListOption;
398+
import com.google.cloud.logging.LoggingOptions;
399+
import com.google.cloud.logging.Payload.StringPayload;
400+
401+
import java.util.Collections;
402+
import java.util.Iterator;
403+
404+
LoggingOptions options = LoggingOptions.defaultInstance();
405+
try(Logging logging = options.service()) {
406+
407+
LogEntry firstEntry = LogEntry.builder(StringPayload.of("message"))
408+
.logName("test-log")
409+
.resource(MonitoredResource.builder("global")
410+
.addLabel("project_id", options.projectId())
411+
.build())
412+
.build();
413+
logging.write(Collections.singleton(firstEntry));
414+
415+
Page<LogEntry> entries = logging.listLogEntries(
416+
EntryListOption.filter("logName=projects/" + options.projectId() + "/logs/test-log"));
417+
Iterator<LogEntry> entryIterator = entries.iterateAll();
418+
while (entryIterator.hasNext()) {
419+
System.out.println(entryIterator.next());
420+
}
421+
}
422+
```
423+
424+
The second snippet shows how to use a `java.util.logging.Logger` to write log entries to Stackdriver
425+
Logging. The snippet installs a Stackdriver Logging handler using
426+
`LoggingHandler.addHandler(Logger, LoggingHandler)`. Notice that this could also be done through the
427+
`logging.properties` file, adding the following line:
428+
```
429+
com.google.cloud.examples.logging.snippets.AddLoggingHandler.handlers=com.google.cloud.logging.LoggingHandler
430+
```
431+
The complete code can be found on
432+
[AddLoggingHandler.java](./gcloud-java-examples/src/main/java/com/google/cloud/examples/logging/snippets/AddLoggingHandler.java).
433+
434+
```java
435+
import com.google.cloud.logging.LoggingHandler;
436+
437+
import java.util.logging.Logger;
438+
439+
Logger logger = Logger.getLogger(AddLoggingHandler.class.getName());
440+
LoggingHandler.addHandler(logger, new LoggingHandler());
441+
logger.warning("test warning");
442+
```
443+
374444
Google Cloud Pub/Sub (Alpha)
375445
----------------------
376446
@@ -554,6 +624,10 @@ Apache 2.0 - See [LICENSE] for more information.
554624
[cloud-dns-docs]: https://cloud.google.com/dns/docs
555625
[cloud-dns-activation]: https://console.cloud.google.com/start/api?id=dns
556626
627+
[logging-api]: http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/cloud/logging/package-summary.html
628+
[stackdriver-logging-docs]: https://cloud.google.com/logging/docs
629+
[stackdriver-logging-activation]: https://console.cloud.google.com/start/api?id=logging
630+
557631
[pubsub-api]: http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/cloud/pubsub/package-summary.html
558632
[cloud-pubsub]: https://cloud.google.com/pubsub/
559633
[cloud-pubsub-docs]: https://cloud.google.com/pubsub/docs

TESTING.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ This library provides tools to help write tests for code that uses the following
66
- [Compute] (#testing-code-that-uses-compute)
77
- [Datastore] (#testing-code-that-uses-datastore)
88
- [DNS] (#testing-code-that-uses-dns)
9+
- [Logging] (#testing-code-that-uses-logging)
910
- [PubSub] (#testing-code-that-uses-pubsub)
1011
- [Resource Manager] (#testing-code-that-uses-resource-manager)
1112
- [Storage] (#testing-code-that-uses-storage)
@@ -146,6 +147,31 @@ You can test against an in-memory local DNS by following these steps:
146147

147148
This method will block until the server thread has been terminated.
148149

150+
### Testing code that uses Logging
151+
152+
Currently, there isn't an emulator for Stackdriver Logging, so an alternative is to create a test
153+
project. `RemoteLoggingHelper` contains convenience methods to make setting up the test project
154+
easier. To use this class, follow the steps below:
155+
156+
1. Create a test Google Cloud project.
157+
158+
2. Download a [JSON service account credentials file][create-service-account] from the Google
159+
Developer's Console.
160+
161+
3. Create a `RemoteLoggingHelper` object using your project ID and JSON key. Here is an example that
162+
uses the `RemoteLoggingHelper` to create a metric.
163+
```java
164+
RemoteLoggingHelper loggingHelper =
165+
RemoteLoggingHelper.create(PROJECT_ID, new FileInputStream("/path/to/my/JSON/key.json"));
166+
Logging logging = loggingHelper.options().service();
167+
// Pick a name for the resource with low probability of clashing
168+
String metricName = RemoteLoggingHelper.formatForTest("test-metric");
169+
MetricInfo metricInfo = MetricInfo.of(name, "logName:syslog");
170+
Metric metric = logging.create(metricInfo);
171+
```
172+
173+
4. Run your tests.
174+
149175
### Testing code that uses Pub/Sub
150176

151177
#### On your machine

gcloud-java-core/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,5 +108,10 @@
108108
<artifactId>gax</artifactId>
109109
<version>0.0.13</version>
110110
</dependency>
111+
<dependency>
112+
<groupId>com.google.api.grpc</groupId>
113+
<artifactId>grpc-core-proto</artifactId>
114+
<version>0.0.4</version>
115+
</dependency>
111116
</dependencies>
112117
</project>
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
/*
2+
* Copyright 2016 Google Inc. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.cloud;
18+
19+
import static com.google.common.base.Preconditions.checkNotNull;
20+
21+
import com.google.common.base.MoreObjects;
22+
import com.google.common.collect.ImmutableMap;
23+
24+
import java.io.Serializable;
25+
import java.util.HashMap;
26+
import java.util.Map;
27+
import java.util.Objects;
28+
29+
/**
30+
* Objects of this class represent a resource that can be used for monitoring, logging, billing, or
31+
* other purposes. Examples include virtual machine instances, databases, and storage devices such
32+
* as disks. The type field identifies a {@link MonitoredResourceDescriptor} object that describes
33+
* the resource's schema. Information in the labels field identifies the actual resource and its
34+
* attributes according to the schema.
35+
*
36+
* <p>For example, the monitored resource for Google Compute Engine VM instances has
37+
* {@code gce_instance} type and specifies values for the labels {@code instance_id} and
38+
* {@code zone} to identify particular VM instances.
39+
*/
40+
public final class MonitoredResource implements Serializable {
41+
42+
private static final long serialVersionUID = -4393604148752640581L;
43+
44+
private final String type;
45+
private final Map<String, String> labels;
46+
47+
/**
48+
* A builder for {@code MonitoredResource} objects.
49+
*/
50+
public static class Builder {
51+
52+
private String type;
53+
private Map<String, String> labels = new HashMap<>();
54+
55+
Builder(String type) {
56+
this.type = type;
57+
}
58+
59+
Builder(MonitoredResource monitoredResource) {
60+
this.type = monitoredResource.type;
61+
this.labels = new HashMap<>(monitoredResource.labels);
62+
}
63+
64+
/**
65+
* Sets the monitored resource type. This value must match the one of
66+
* {@link MonitoredResourceDescriptor#type()} of a {@code MonitoredResourceDescriptor} object.
67+
* For example, the type {@code cloudsql_database} represent databases in Google Cloud SQL.
68+
*/
69+
public Builder type(String type) {
70+
this.type = type;
71+
return this;
72+
}
73+
74+
/**
75+
* Sets the values for all the labels required by the corresponding monitored resource
76+
* descriptor (see {@link MonitoredResourceDescriptor#labels()}. For example, Google Compute
77+
* Engine VM instances use the labels {@code instance_id} and {@code zone}.
78+
*/
79+
public Builder labels(Map<String, String> labels) {
80+
this.labels = new HashMap<>(checkNotNull(labels));
81+
return this;
82+
}
83+
84+
/**
85+
* Adds a label to the labels of the monitored resource.
86+
*/
87+
public Builder addLabel(String key, String value) {
88+
this.labels.put(key, value);
89+
return this;
90+
}
91+
92+
/**
93+
* Clears all the labels of the monitored resource.
94+
*/
95+
public Builder clearLabels() {
96+
this.labels.clear();
97+
return this;
98+
}
99+
100+
public MonitoredResource build() {
101+
return new MonitoredResource(this);
102+
}
103+
}
104+
105+
MonitoredResource(Builder builder) {
106+
this.type = checkNotNull(builder.type);
107+
this.labels = ImmutableMap.copyOf(builder.labels);
108+
}
109+
110+
/**
111+
* Returns the monitored resource type. This value must match the one of
112+
* {@link MonitoredResourceDescriptor#type()} of a {@code MonitoredResourceDescriptor} object.
113+
* For example, the type {@code cloudsql_database} represent databases in Google Cloud SQL.
114+
*/
115+
public String type() {
116+
return type;
117+
}
118+
119+
/**
120+
* Returns the values for all the labels required by the corresponding monitored resource
121+
* descriptor (see {@link MonitoredResourceDescriptor#labels()}. For example, Google Compute
122+
* Engine VM instances use the labels {@code instance_id} and {@code zone}.
123+
*/
124+
public Map<String, String> labels() {
125+
return labels;
126+
}
127+
128+
@Override
129+
public int hashCode() {
130+
return Objects.hash(type, labels);
131+
}
132+
133+
@Override
134+
public boolean equals(Object obj) {
135+
if (obj == this) {
136+
return true;
137+
}
138+
if (!(obj instanceof MonitoredResource)) {
139+
return false;
140+
}
141+
MonitoredResource other = (MonitoredResource) obj;
142+
return Objects.equals(type, other.type) && Objects.equals(labels, other.labels);
143+
}
144+
145+
@Override
146+
public String toString() {
147+
return MoreObjects.toStringHelper(this)
148+
.add("type", type)
149+
.add("labels", labels)
150+
.toString();
151+
}
152+
153+
public com.google.api.MonitoredResource toPb() {
154+
return com.google.api.MonitoredResource.newBuilder()
155+
.setType(type)
156+
.putAllLabels(labels)
157+
.build();
158+
}
159+
160+
/**
161+
* Returns a builder for this {@code MonitoredResource} object.
162+
*/
163+
public Builder toBuilder() {
164+
return new Builder(this);
165+
}
166+
167+
/**
168+
* Returns a builder for {@code MonitoredResource} objects given the resource's type.
169+
*/
170+
public static Builder builder(String type) {
171+
return new Builder(type);
172+
}
173+
174+
/**
175+
* Creates a {@code MonitoredResource} object given the resource's type and labels.
176+
*/
177+
public static MonitoredResource of(String type, Map<String, String> labels) {
178+
return builder(type).labels(labels).build();
179+
}
180+
181+
public static MonitoredResource fromPb(com.google.api.MonitoredResource descriptorPb) {
182+
return new Builder(descriptorPb.getType()).labels(descriptorPb.getLabels()).build();
183+
}
184+
}

0 commit comments

Comments
 (0)