Using an Ops Service
Examine Ops services and how to construct a basic chatbot.
We'll cover the following...
We are not going to go into complete detail about this service, as we have covered how gRPC works in previous sections. As this service makes gRPC or REST calls to other services, let's talk about the calls that need to be implemented.
The protocol buffer service definition is as follows:
service Ops {rpc ListTraces(ListTracesReq) returns (ListTracesResp) {};rpc ShowTrace(ShowTraceReq) returns (ShowTraceResp) {};rpc ChangeSampling(ChangeSamplingReq) returns (ChangeSamplingResp) {};rpc DeployedVersion(DeployedVersionReq) returns (DeployedVersionResp) {};rpc Alerts(AlertsReq) returns (AlertsResp) {};}
For our example service, these RPCs are targeted at a single deployed instance, but in a production environment, this would work on multiple entities that exist on a site.
This allows users to get some information quickly, such as the following:
See the traces we have in a certain time period, and the ability to filter by tags (such as
error
).Retrieve basic trace data and the Jaeger URL of a trace given a trace ID.
Change the sampling type and rate for traces in the service.
Tell us what version has been deployed according to Prometheus.
Display any alerts that Prometheus shows are firing.
We can read the code on how this is implemented below:
# Ops Service The Ops service provides API access to various operational information that we want to allow various tool access to. While this could be built into the chatbot.go binary that implements the ChatOps interface, this abstraction allows us to have multiple programs that can access these API calls. In addition, if we want to migrate to another chat service instead of Slack (like Microsoft Teams), we can easily do so without impacting users during a migration. ## Basic Architecture This is your standard gRPC service with a nice Go client ready made to access the service. We stick the important parts in `internal` to keep anyone from using the packages that are just for the service. `proto/` contains the protocol buffer messages we have for the client/server communication. The file directory layout is as follows (with some highlighted files, but not all files): ``` ├── client │ └── client.go ├── internal │ ├── jaeger │ │ └── client │ │ ├── client.go │ │ └── test │ ├── prom │ │ └── prom.go │ └── server │ └── server.go ├── ops.go └── proto ├── jaeger │ ├── model ├── ops.pb.go ├── ops.proto └── ops_grpc.pb.go ``` * `ops.go` is the main file for the Ops service * `client/ provides` a client library for accessing our Ops service using Go * `internal/jaeger` provides a client wrapper for accessing Jaeger and some end to end testing * `internal/prom` provides a client wrapper for accessing prometheus * `proto/` contains protocol buffer messages and services for accessing the Ops service via gRPC * `proto/jaeger` provides various protocol buffers required to access Jaeger
We include a README
file that goes over the basic architecture, but it is your standard gRPC service that makes calls using gRPC to the Petstore service/Jaeger and REST calls to ...