java - 在 Java 中审计 gRPC 调用
问题描述
我正在尝试创建一个ServerInterceptor
来审核对 gRPC API 的所有调用。我想为每次调用 API 组合一个具有如下所示结构的对象。这些调用都是一元调用——一个简单的请求和响应。
public class ApiAudit {
private Map<String, String> headers;
private long processTime;
private String api;
private String protocol;
private String requestBody;
private String responseBody;
private int responseCode;
private String errorMessage;
private boolean isDeprecated;
}
我的挑战是似乎没有一个地方可以收集这些信息。例如,如果这是一个 REST API,我可以创建一个过滤器,该过滤器可以访问请求和响应对象,其中包含所有标头等,并且可以将过滤器链调用包装在 try/catch 中以确定是否存在错误等。但是,对于 gRPC,所有这些不同的部分都有些脱节。在方法中接收标头,如果我创建一个并覆盖该方法,ServerInterceptor#interceptCall
则可以访问请求对象,如果我创建一个并覆盖该对象,则可以访问响应对象,并且我可以覆盖该方法SimpleForwardingServerCallListener
onMessage
SimpleForwardingServerCall
sendMessage
onHalfComplete
SimpleForwardingServerCallListener
并将调用包装在 try/catch 中以确定调用是否成功。如何将所有这些信息放在一个对象中,以单行形式写入日志或存储在审计数据库中?
解决方案
您应该覆盖您感兴趣的每个调用,复制出您需要的数据。然后在onComplete()
/onCancel()
你将数据存储到数据库中。onComplete()
/onCancel()
始终是 RPC 的结尾(尽管意识到发送可以在取消之后发生,因为处理取消是不正当的;之后的任何内容onCancel()
都被 grpc 丢弃)。
您将创建一个(转发)ServerCall 和一个(转发)ServerCall.Listener。要将数据存储在“一个地方”,您可以简单地让一个对象引用另一个对象(例如,嵌套类)。
请注意,制作 的完整副本非常Metadata
重要,因为它不是线程安全的对象。
Metadata copy = new Metadata();
copy.merge(headers);
next.interceptCall(call, headers);
推荐阅读
- python - 数组元素的 Numpy 内存分配
- java - 创建简单的休眠应用程序时出现“表不存在”错误
- java - 用于读取 GPIO 引脚状态变化的 Java epoll 选择器
- python - pyparsing - 如何提前查找不明确的语法(带有/不带时区解析的时间戳)
- java - 遍历 HashMap 中的值并查看特定 HashSet 出现次数的算法
- powerbi - DAX - 如何根据索引计算两个表中缺少的行
- node.js - 在节点 js 中导入
- javascript - 使用 document.createElement 测试该元素的 scrollHeight 和 clientHeight 时,值始终为 0
- ubuntu - Ubuntu 终端中 Vim 的边缘未填充颜色方案
- java - 仅当 BufferedReader 中有数据时如何创建文件?