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

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ public final class IpcLogEntry {

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

private String protocol;

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

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

private String clientRegion;
private String clientZone;
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,22 @@ 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) {
return withMethod(method.value());
}

/**
* Set the method used for this request.
*/
public IpcLogEntry withMethod(String 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 @@ -899,6 +925,7 @@ public String toString() {
.addField("protocol", protocol)
.addField("uri", uri)
.addField("path", path)
.addField("method", method)
.addField("endpoint", endpoint)
.addField("vip", vip)
.addField("clientRegion", clientRegion)
Expand All @@ -918,6 +945,7 @@ public String toString() {
.addField("attempt", attempt)
.addField("attemptFinal", attemptFinal)
.addField("result", result)
.addField("source", source)
.addField("status", status)
.addField("statusDetail", statusDetail)
.addField("exceptionClass", getExceptionClass())
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/**
* 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;

@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 @@ -49,7 +49,9 @@ public enum IpcMetric {
IpcTagKey.status
),
EnumSet.of(
IpcTagKey.source,
ayangster marked this conversation as resolved.
Show resolved Hide resolved
IpcTagKey.endpoint,
IpcTagKey.method,
IpcTagKey.failureInjected,
IpcTagKey.httpMethod,
IpcTagKey.httpStatus,
Expand All @@ -74,7 +76,9 @@ public enum IpcMetric {
IpcTagKey.status
),
EnumSet.of(
IpcTagKey.source,
IpcTagKey.endpoint,
IpcTagKey.method,
IpcTagKey.clientApp,
IpcTagKey.clientCluster,
IpcTagKey.clientAsg,
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();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ public enum IpcTagKey {
*/
result("ipc.result"),

/**
* Indicates where the result was ultimately sourced from such as cache, direct,
* proxy, fallback, etc. See {@link IpcSource} for possible values.
*/
source("ipc.source"),

/**
* Dimension indicating a high level status for the request. These values are the same
* for all implementations to make it easier to query across services. See {@link IpcStatus}
Expand All @@ -41,8 +47,9 @@ public enum IpcTagKey {

/**
* Optional dimension indicating a more detailed status. The values for this are
* implementation specific. For example with HTTP, the status code would be a likely
* value used here.
* implementation specific. For example, the {@link #status} may be
* {@code connection_error} and {@code statusDetail} would be {@code no_servers},
* {@code connect_timeout}, {@code ssl_handshake_failure}, etc.
*/
statusDetail("ipc.status.detail"),

Expand Down Expand Up @@ -103,6 +110,11 @@ public enum IpcTagKey {
*/
protocol("ipc.protocol"),

/**
* Method used to make the IPC request. See {@link IpcMethod} for possible values.
*/
method("ipc.method"),

/**
* Region where the client is located.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,26 @@ public void endpointViaUri404() {
Assertions.assertEquals("unknown", actual);
}

@Test
public void method() {
String expected = IpcMethod.get.value();
String actual = (String) entry
.withMethod(IpcMethod.get)
.convert(this::toMap)
.get("method");
Assertions.assertEquals(expected, actual);
}

@Test
public void customMethod() {
String expected = "websocket";
String actual = (String) entry
.withMethod(expected)
.convert(this::toMap)
.get("method");
Assertions.assertEquals(expected, actual);
}

@Test
public void clientNode() {
String expected = "i-12345";
Expand Down Expand Up @@ -458,6 +478,15 @@ public void addResponseEndpointHeader() {
Assertions.assertEquals("/api/v1/test", map.get("endpoint"));
}

@Test
public void source() {
String expected = IpcSource.direct.value();
String actual = (String) entry
.withSource(IpcSource.direct)
.convert(this::toMap).get("source");
Assertions.assertEquals(expected, actual);
}

@Test
public void httpStatusOk() {
String actual = (String) entry
Expand Down
Loading