Skip to content

Commit 5ff2a49

Browse files
author
cindy-peng
committed
feat: Add Cloud Run Jobs support
1 parent edd828b commit 5ff2a49

File tree

3 files changed

+677
-611
lines changed

3 files changed

+677
-611
lines changed

google-cloud-logging/src/main/java/com/google/cloud/logging/MetadataLoader.java

Lines changed: 200 additions & 179 deletions
Original file line numberDiff line numberDiff line change
@@ -20,189 +20,210 @@
2020

2121
import com.google.cloud.logging.MonitoredResourceUtil.Label;
2222
import com.google.common.collect.ImmutableMap;
23+
2324
import java.io.IOException;
2425
import java.nio.file.Files;
2526
import java.nio.file.Paths;
2627
import java.util.function.Supplier;
2728

2829
public final class MetadataLoader {
29-
public static final String ENV_FLEXIBLE = "flex";
30-
public static final String ENV_STANDARD = "standard";
31-
32-
private final ResourceTypeEnvironmentGetter getter;
33-
34-
private final ImmutableMap<Label, Supplier<String>> labelResolvers =
35-
ImmutableMap.<Label, Supplier<String>>builder()
36-
.put(Label.ClusterName, this::getClusterName)
37-
.put(Label.ConfigurationName, this::getConfigName)
38-
.put(Label.ContainerName, this::getContainerName)
39-
.put(Label.Env, this::getEnv)
40-
.put(Label.FunctionName, this::getFunctionName)
41-
.put(Label.InstanceId, this::getInstanceId)
42-
.put(Label.InstanceName, this::getInstanceName)
43-
.put(Label.CloudRunLocation, this::getCloudRunLocation)
44-
.put(Label.GKELocation, this::getGKELocation)
45-
.put(Label.ModuleId, this::getModuleId)
46-
.put(Label.NamespaceName, this::getNamespaceName)
47-
.put(Label.PodName, this::getPodName)
48-
.put(Label.ProjectId, this::getProjectId)
49-
.put(Label.Region, this::getRegion)
50-
.put(Label.RevisionName, this::getRevisionName)
51-
.put(Label.ServiceName, this::getServiceName)
52-
.put(Label.VersionId, this::getVersionId)
53-
.put(Label.Zone, this::getZone)
54-
.buildOrThrow();
55-
56-
public MetadataLoader(ResourceTypeEnvironmentGetter getter) {
57-
this.getter = getter;
58-
}
59-
60-
/**
61-
* Loads metadata value for the {@code label} argument.
62-
*
63-
* @param label A resource metadata label of type {@see MonitoredResourceUtil.Label}
64-
* @return A string with metadata value or {@code null} if the label is not supported.
65-
*/
66-
public String getValue(MonitoredResourceUtil.Label label) {
67-
Supplier<String> lambda = labelResolvers.get(label);
68-
if (lambda != null) {
69-
return lambda.get();
70-
}
71-
return null;
72-
}
73-
74-
private String getClusterName() {
75-
return getter.getAttribute("instance/attributes/cluster-name");
76-
}
77-
78-
private String getConfigName() {
79-
return getter.getEnv("K_CONFIGURATION");
80-
}
81-
82-
// due to lack of options to discover container name from within process
83-
// allow users to provide the container name via environment variable
84-
private String getContainerName() {
85-
return getter.getEnv("CONTAINER_NAME");
86-
}
87-
/**
88-
* Distinguish between Standard and Flexible GAE environments. There is no indicator of the
89-
* environment. The path to the startup-script in the metadata attribute was selected as one of
90-
* the new values that explicitly mentioning "flex" and cannot be altered by user (e.g.
91-
* environment variable). The method assumes that the resource type is already identified as
92-
* {@link Resource.AppEngine}.
93-
*
94-
* @return {@link MetadataLoader.ENV_FLEXIBLE} for the Flexible environment and {@link
95-
* MetadataLoader.ENV_STANDARD} for the Standard environment.
96-
*/
97-
private String getEnv() {
98-
String value = getter.getAttribute("instance/attributes/startup-script");
99-
if ("/var/lib/flex/startup_script.sh".equals(value)) {
100-
return ENV_FLEXIBLE;
101-
}
102-
return ENV_STANDARD;
103-
}
104-
105-
private String getFunctionName() {
106-
String value = getter.getEnv("K_SERVICE");
107-
if (value == null) {
108-
// keep supporting custom function name if is not provided by default
109-
// for backward compatibility only; reconsider removing it after Gen2
110-
// environment is enrolled for Cloud Function
111-
value = getter.getEnv("FUNCTION_NAME");
112-
}
113-
return value;
114-
}
115-
116-
private String getInstanceId() {
117-
return getter.getAttribute("instance/id");
118-
}
119-
120-
private String getInstanceName() {
121-
return getter.getAttribute("instance/name");
122-
}
123-
124-
private String getCloudRunLocation() {
125-
return getRegion();
126-
}
127-
128-
private String getGKELocation() {
129-
return getZone();
130-
}
131-
132-
private String getModuleId() {
133-
return getter.getEnv("GAE_SERVICE");
134-
}
135-
/**
136-
* Heuristic to discover the namespace name of the current environment. There is no deterministic
137-
* way to discover the namespace name of the process. The name is read from the {@link
138-
* K8S_POD_NAMESPACE_PATH} when available or read from a user defined environment variable
139-
* "NAMESPACE_NAME"
140-
*
141-
* @return Namespace string or null if the name could not be discovered
142-
*/
143-
private String getNamespaceName() {
144-
String value = null;
145-
try {
146-
value =
147-
new String(
148-
Files.readAllBytes(
149-
Paths.get("/var/run/secrets/kubernetes.io/serviceaccount/namespace")),
150-
UTF_8);
151-
} catch (IOException e) {
152-
// if SA token is not shared the info about namespace is unavailable
153-
// allow users to define the namespace name explicitly
154-
value = getter.getEnv("NAMESPACE_NAME");
155-
}
156-
return value;
157-
}
158-
// Kubernetes set hostname of the pod to the pod name by default, however hostname can be override
159-
// in manifest
160-
// allow users to provide the container name via environment variable
161-
private String getPodName() {
162-
String value = getter.getEnv("POD_NAME");
163-
if (value != null) {
164-
return value;
165-
}
166-
return getter.getEnv("HOSTNAME");
167-
}
168-
169-
private String getProjectId() {
170-
return getter.getAttribute("project/project-id");
171-
}
172-
/**
173-
* Retrieves a region from the qualified region of 'projects/[PROJECT_NUMBER]/regions/[REGION]'
174-
*
175-
* @return region string id
176-
*/
177-
private String getRegion() {
178-
String loc = getter.getAttribute("instance/region");
179-
if (loc != null) {
180-
return loc.substring(loc.lastIndexOf('/') + 1);
181-
}
182-
return null;
183-
}
184-
185-
private String getRevisionName() {
186-
return getter.getEnv("K_REVISION");
187-
}
188-
189-
private String getServiceName() {
190-
return getter.getEnv("K_SERVICE");
191-
}
192-
193-
private String getVersionId() {
194-
return getter.getEnv("GAE_VERSION");
195-
}
196-
/**
197-
* Retrieves a zone from the qualified zone of 'projects/[PROJECT_NUMBER]/zones/[ZONE]'
198-
*
199-
* @return zone string id
200-
*/
201-
private String getZone() {
202-
String loc = getter.getAttribute("instance/zone");
203-
if (loc != null) {
204-
return loc.substring(loc.lastIndexOf('/') + 1);
205-
}
206-
return null;
207-
}
30+
public static final String ENV_FLEXIBLE = "flex";
31+
public static final String ENV_STANDARD = "standard";
32+
33+
private final ResourceTypeEnvironmentGetter getter;
34+
35+
private final ImmutableMap<Label, Supplier<String>> labelResolvers =
36+
ImmutableMap.<Label, Supplier<String>>builder()
37+
.put(Label.ClusterName, this::getClusterName)
38+
.put(Label.ConfigurationName, this::getConfigName)
39+
.put(Label.ContainerName, this::getContainerName)
40+
.put(Label.Env, this::getEnv)
41+
.put(Label.FunctionName, this::getFunctionName)
42+
.put(Label.InstanceId, this::getInstanceId)
43+
.put(Label.InstanceName, this::getInstanceName)
44+
.put(Label.CloudRunJobName, this::getCloudRunJobName)
45+
.put(Label.CloudRunJobExecutionName, this::getCloudRunJobExecutionName)
46+
.put(Label.CloudRunJobTaskIndex, this::getCloudRunJobTaskIndex)
47+
.put(Label.CloudRunLocation, this::getCloudRunLocation)
48+
.put(Label.GKELocation, this::getGKELocation)
49+
.put(Label.ModuleId, this::getModuleId)
50+
.put(Label.NamespaceName, this::getNamespaceName)
51+
.put(Label.PodName, this::getPodName)
52+
.put(Label.ProjectId, this::getProjectId)
53+
.put(Label.Region, this::getRegion)
54+
.put(Label.RevisionName, this::getRevisionName)
55+
.put(Label.ServiceName, this::getServiceName)
56+
.put(Label.VersionId, this::getVersionId)
57+
.put(Label.Zone, this::getZone)
58+
.buildOrThrow();
59+
60+
public MetadataLoader(ResourceTypeEnvironmentGetter getter) {
61+
this.getter = getter;
62+
}
63+
64+
/**
65+
* Loads metadata value for the {@code label} argument.
66+
*
67+
* @param label A resource metadata label of type {@see MonitoredResourceUtil.Label}
68+
* @return A string with metadata value or {@code null} if the label is not supported.
69+
*/
70+
public String getValue(MonitoredResourceUtil.Label label) {
71+
Supplier<String> lambda = labelResolvers.get(label);
72+
if (lambda != null) {
73+
return lambda.get();
74+
}
75+
return null;
76+
}
77+
78+
private String getClusterName() {
79+
return getter.getAttribute("instance/attributes/cluster-name");
80+
}
81+
82+
private String getConfigName() {
83+
return getter.getEnv("K_CONFIGURATION");
84+
}
85+
86+
// due to lack of options to discover container name from within process
87+
// allow users to provide the container name via environment variable
88+
private String getContainerName() {
89+
return getter.getEnv("CONTAINER_NAME");
90+
}
91+
92+
/**
93+
* Distinguish between Standard and Flexible GAE environments. There is no indicator of the
94+
* environment. The path to the startup-script in the metadata attribute was selected as one of
95+
* the new values that explicitly mentioning "flex" and cannot be altered by user (e.g.
96+
* environment variable). The method assumes that the resource type is already identified as
97+
* {@link Resource.AppEngine}.
98+
*
99+
* @return {@link MetadataLoader.ENV_FLEXIBLE} for the Flexible environment and {@link
100+
* MetadataLoader.ENV_STANDARD} for the Standard environment.
101+
*/
102+
private String getEnv() {
103+
String value = getter.getAttribute("instance/attributes/startup-script");
104+
if ("/var/lib/flex/startup_script.sh".equals(value)) {
105+
return ENV_FLEXIBLE;
106+
}
107+
return ENV_STANDARD;
108+
}
109+
110+
private String getFunctionName() {
111+
String value = getter.getEnv("K_SERVICE");
112+
if (value == null) {
113+
// keep supporting custom function name if is not provided by default
114+
// for backward compatibility only; reconsider removing it after Gen2
115+
// environment is enrolled for Cloud Function
116+
value = getter.getEnv("FUNCTION_NAME");
117+
}
118+
return value;
119+
}
120+
121+
private String getInstanceId() {
122+
return getter.getAttribute("instance/id");
123+
}
124+
125+
private String getInstanceName() {
126+
return getter.getAttribute("instance/name");
127+
}
128+
129+
private String getCloudRunJobName() {
130+
return getter.getEnv("CLOUD_RUN_JOB");
131+
}
132+
133+
private String getCloudRunJobExecutionName() {
134+
return getter.getEnv("CLOUD_RUN_EXECUTION");
135+
}
136+
137+
private String getCloudRunJobTaskIndex() {
138+
return getter.getEnv("CLOUD_RUN_TASK_INDEX");
139+
}
140+
141+
private String getCloudRunLocation() {
142+
return getRegion();
143+
}
144+
145+
private String getGKELocation() {
146+
return getZone();
147+
}
148+
149+
private String getModuleId() {
150+
return getter.getEnv("GAE_SERVICE");
151+
}
152+
153+
/**
154+
* Heuristic to discover the namespace name of the current environment. There is no deterministic
155+
* way to discover the namespace name of the process. The name is read from the {@link
156+
* K8S_POD_NAMESPACE_PATH} when available or read from a user defined environment variable
157+
* "NAMESPACE_NAME"
158+
*
159+
* @return Namespace string or null if the name could not be discovered
160+
*/
161+
private String getNamespaceName() {
162+
String value = null;
163+
try {
164+
value =
165+
new String(
166+
Files.readAllBytes(
167+
Paths.get("/var/run/secrets/kubernetes.io/serviceaccount/namespace")),
168+
UTF_8);
169+
} catch (IOException e) {
170+
// if SA token is not shared the info about namespace is unavailable
171+
// allow users to define the namespace name explicitly
172+
value = getter.getEnv("NAMESPACE_NAME");
173+
}
174+
return value;
175+
}
176+
177+
// Kubernetes set hostname of the pod to the pod name by default, however hostname can be override
178+
// in manifest
179+
// allow users to provide the container name via environment variable
180+
private String getPodName() {
181+
String value = getter.getEnv("POD_NAME");
182+
if (value != null) {
183+
return value;
184+
}
185+
return getter.getEnv("HOSTNAME");
186+
}
187+
188+
private String getProjectId() {
189+
return getter.getAttribute("project/project-id");
190+
}
191+
192+
/**
193+
* Retrieves a region from the qualified region of 'projects/[PROJECT_NUMBER]/regions/[REGION]'
194+
*
195+
* @return region string id
196+
*/
197+
private String getRegion() {
198+
String loc = getter.getAttribute("instance/region");
199+
if (loc != null) {
200+
return loc.substring(loc.lastIndexOf('/') + 1);
201+
}
202+
return null;
203+
}
204+
205+
private String getRevisionName() {
206+
return getter.getEnv("K_REVISION");
207+
}
208+
209+
private String getServiceName() {
210+
return getter.getEnv("K_SERVICE");
211+
}
212+
213+
private String getVersionId() {
214+
return getter.getEnv("GAE_VERSION");
215+
}
216+
217+
/**
218+
* Retrieves a zone from the qualified zone of 'projects/[PROJECT_NUMBER]/zones/[ZONE]'
219+
*
220+
* @return zone string id
221+
*/
222+
private String getZone() {
223+
String loc = getter.getAttribute("instance/zone");
224+
if (loc != null) {
225+
return loc.substring(loc.lastIndexOf('/') + 1);
226+
}
227+
return null;
228+
}
208229
}

0 commit comments

Comments
 (0)