Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new IPC tags #1168

Merged
merged 13 commits into from
Feb 6, 2025
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ public void successfulRequest() {
Assertions.assertEquals(millis(42), t.totalTime());
Assertions.assertEquals("EC2.DescribeInstances", get(t.id(), "ipc.endpoint"));
Assertions.assertEquals("200", get(t.id(), "http.status"));
Assertions.assertEquals("POST", get(t.id(), "http.method"));
Assertions.assertEquals("post", get(t.id(), "http.method"));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
Expand All @@ -52,6 +53,7 @@ public final class IpcLogEntry {

private String owner;
private IpcResult result;
private IpcSource source;

private String protocol;

Expand All @@ -64,6 +66,7 @@ public final class IpcLogEntry {

private String vip;
private String endpoint;
private IpcMethod method;

private String clientRegion;
private String clientZone;
Expand All @@ -79,7 +82,6 @@ public final class IpcLogEntry {
private String serverAsg;
private String serverNode;

private String httpMethod;
private int httpStatus;

private String uri;
Expand Down Expand Up @@ -208,6 +210,14 @@ public IpcLogEntry withResult(IpcResult result) {
return this;
}

/**
* Set the source for this request. See {@link IpcSource} for more information.
*/
public IpcLogEntry withSource(IpcSource source) {
this.source = source;
return this;
}

/**
* Set the high level status for the request. See {@link IpcStatus} for more
* information.
Expand Down Expand Up @@ -307,6 +317,14 @@ public IpcLogEntry withEndpoint(String endpoint) {
return this;
}

/**
* Set the method used for this request. See {@link IpcMethod} for possible values.
*/
public IpcLogEntry withMethod(IpcMethod method) {
this.method = method;
return this;
}

/**
* Set the client region for the request. In the case of the server side this will be
* automatically filled in if the {@link NetflixHeader#Zone} is specified on the client
Expand Down Expand Up @@ -459,7 +477,13 @@ public IpcLogEntry withServerNode(String node) {
* Set the HTTP method used for this request.
*/
public IpcLogEntry withHttpMethod(String method) {
this.httpMethod = method;
try {
IpcMethod m = IpcMethod.valueOf(method.toLowerCase(Locale.US));
withMethod(m);
} catch (Exception e) {
// Ignore invalid methods
withMethod(IpcMethod.unknown);
}
return this;
}

Expand Down Expand Up @@ -625,6 +649,12 @@ private void putTag(Map<String, String> tags, String k, String v) {
}
}

private void putTag(Map<String, String> tags, String k, Enum<?> v) {
if (v != null) {
putTag(tags, k, v.name());
}
}

private void finalizeFields() {
// Do final checks and update fields that haven't been explicitly set if needed
// before logging.
Expand Down Expand Up @@ -685,7 +715,7 @@ private Id createCallId(String name) {
putTag(tags, IpcTagKey.protocol.key(), protocol);
putTag(tags, IpcTagKey.statusDetail.key(), statusDetail);
putTag(tags, IpcTagKey.httpStatus.key(), Integer.toString(httpStatus));
putTag(tags, IpcTagKey.httpMethod.key(), httpMethod);
putTag(tags, IpcTagKey.httpMethod.key(), method);

return registry.createId(name, tags);
}
Expand Down Expand Up @@ -855,6 +885,7 @@ void populateMDC() {
putInMDC("uri", uri);
putInMDC("path", path);
putInMDC(IpcTagKey.endpoint.key(), endpoint);
putInMDC(method);

putInMDC(IpcTagKey.owner.key(), owner);
putInMDC(IpcTagKey.protocol.key(), protocol);
Expand All @@ -881,10 +912,10 @@ void populateMDC() {
putInMDC(attemptFinal);

putInMDC(result);
putInMDC(source);
putInMDC(status);
putInMDC(IpcTagKey.statusDetail.key(), statusDetail);

putInMDC(IpcTagKey.httpMethod.key(), httpMethod);
putInMDC(IpcTagKey.httpStatus.key(), Integer.toString(httpStatus));
}

Expand All @@ -899,6 +930,7 @@ public String toString() {
.addField("protocol", protocol)
.addField("uri", uri)
.addField("path", path)
.addField("method", method)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Source and method should also get updated in reset() and perhaps populateMDC() so it will be available for logs.

.addField("endpoint", endpoint)
.addField("vip", vip)
.addField("clientRegion", clientRegion)
Expand All @@ -918,11 +950,11 @@ public String toString() {
.addField("attempt", attempt)
.addField("attemptFinal", attemptFinal)
.addField("result", result)
.addField("source", source)
.addField("status", status)
.addField("statusDetail", statusDetail)
.addField("exceptionClass", getExceptionClass())
.addField("exceptionMessage", getExceptionMessage())
.addField("httpMethod", httpMethod)
.addField("httpStatus", httpStatus)
.addField("requestContentLength", requestContentLength)
.addField("responseContentLength", responseContentLength)
Expand All @@ -945,6 +977,7 @@ void reset() {
latency = -1L;
owner = null;
result = null;
source = null;
protocol = null;
status = null;
statusDetail = null;
Expand All @@ -953,6 +986,7 @@ void reset() {
attemptFinal = null;
vip = null;
endpoint = null;
method = null;
clientRegion = null;
clientZone = null;
clientApp = null;
Expand All @@ -965,7 +999,6 @@ void reset() {
serverCluster = null;
serverAsg = null;
serverNode = null;
httpMethod = null;
httpStatus = -1;
uri = null;
path = null;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/*
* Copyright 2024 Netflix, Inc.
*
* 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.netflix.spectator.ipc;

import com.netflix.spectator.api.Tag;

public enum IpcMethod implements Tag {

/**
* Represents a unary gRPC method.
*/
unary,

/**
* Represents a client streaming gRPC method.
*/
client_streaming,

/**
* Represents a server streaming gRPC method.
*/
server_streaming,

/**
* Represents a bidirectional streaming gRPC method.
*/
bidi_streaming,

/**
* Represents an HTTP GET request.
*/
get,

/**
* Represents an HTTP POST request.
*/
post,

/**
* Represents an HTTP PUT request.
*/
put,

/**
* Represents an HTTP PATCH request.
*/
patch,

/**
* Represents an HTTP DELETE request.
*/
delete,

/**
* Represents an HTTP OPTIONS request.
*/
options,

/**
* Represents a GraphQL query.
*/
query,

/**
* Represents a GraphQL mutation.
*/
mutation,

/**
* Represents a GraphQL subscription.
*/
subscription,

/**
* Represents a method that is not supported.
*/
unknown;

@Override public String key() {
return IpcTagKey.method.key();
}

@Override public String value() {
return name();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,43 @@ public enum IpcMetric {
IpcTagKey.protocol,
IpcTagKey.vip
)
),

/**
* V2 - Timer recording the number and latency of outbound requests.
*/
apiClientCall(
"api.client.call",
EnumSet.of(
IpcTagKey.vip,
IpcTagKey.method,
IpcTagKey.endpoint,
IpcTagKey.owner,
IpcTagKey.id,
IpcTagKey.source,
IpcTagKey.result,
IpcTagKey.status,
IpcTagKey.statusDetail
),
EnumSet.noneOf(IpcTagKey.class)
),

/**
* V2 - Timer recording the number and latency of inbound requests.
*/
apiServerCall(
"api.server.call",
EnumSet.of(
IpcTagKey.method,
IpcTagKey.endpoint,
IpcTagKey.owner,
IpcTagKey.id,
IpcTagKey.source,
IpcTagKey.result,
IpcTagKey.status,
IpcTagKey.statusDetail
),
EnumSet.noneOf(IpcTagKey.class)
);

private final String metricName;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* Copyright 2024 Netflix, Inc.
*
* 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.netflix.spectator.ipc;

import com.netflix.spectator.api.Tag;

public enum IpcSource implements Tag {

/**
* No call was made due to errors potentially.
*/
none,

/**
* Data sourced directly from EVCache as the cache implementation (when the exact cache is known).
*/
evcache,

/**
* Data sourced from a cache where the cache implementation is not directly known or abstracted.
*/
cache,

/**
* Static fallback was used to fetch the data.
*/
fallback,

/**
* Response fetched using mesh.
*/
mesh,

/**
* Response fetched directly from the downstream service (or if not known to be mesh).
*/
direct,

/**
* Data sourced from a validation handler that may short-circuit the response immediately for failed validation.
*/
validation,

/**
* Data sourced and returned directly by a filter or interceptor.
*/
filter,

/**
* Data fetched from an in-memory cache.
*/
memory,

/**
* Data sourced from a user defined business logic handler or root data fetcher.
*/
application;

@Override
public String key() {
return IpcTagKey.source.key();
}

@Override
public String value() {
return name();
}
}
Loading
Loading