1 //
2 // Copyright 2022 gRPC authors.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //     http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
17 #ifndef GRPCPP_EXT_GCP_OBSERVABILITY_H
18 #define GRPCPP_EXT_GCP_OBSERVABILITY_H
19 
20 #include <grpc/support/port_platform.h>
21 
22 #include "absl/status/status.h"
23 #include "absl/status/statusor.h"
24 
25 #include <grpcpp/impl/grpc_library.h>
26 
27 namespace grpc {
28 
29 // GcpObservability objects follow the RAII idiom and help manage the lifetime
30 // of gRPC Observability data exporting to GCP. `GcpObservability::Init()`
31 // should be invoked instead to return an `GcpObservability` instance.
32 // Observability data is flushed at regular intervals, and also when this
33 // instance goes out of scope and its destructor is invoked.
34 class GcpObservability {
35  public:
36   // Initialize GCP Observability for gRPC.
37   // This should be called before any other gRPC operations like creating a
38   // channel, server, credentials etc.
39   // The return value helps determine whether observability was
40   // successfully enabled or not. On success, an object of class `Observability`
41   // is returned. When this object goes out of scope, GCP Observability stats,
42   // tracing and logging data is flushed. On failure, the status message can be
43   // used to determine the cause of failure. It is up to the applications to
44   // either crash on failure, or continue without GCP observability being
45   // enabled. The status codes do not have any special meaning at present, and
46   // users should not make any assumptions based on the status code, other than
47   // a non-OK status code meaning that observability initialization failed.
48   //
49   // The expected usage is to call this at the top (or near the top) in
50   // main(), and let it go out of scope after all RPCs and activities that we
51   // want to observe are done. Please look at
52   // https://github.com/grpc/grpc/blob/master/examples/cpp/gcp_observability/helloworld/greeter_client.cc
53   // and
54   // https://github.com/grpc/grpc/blob/master/examples/cpp/gcp_observability/helloworld/greeter_server.cc
55   // for sample usage.
56   //
57   // It is possible for an initialized GcpObservability object to go out of
58   // scope while RPCs and other gRPC operations are still ongoing. In this case,
59   // GCP Observability tries to flush all observability data collected till that
60   // point.
61   //
62   // Note that this is a blocking call which properly sets up gRPC Observability
63   // to work with GCP and might take a few seconds to return.  Similarly, the
64   // destruction of a non-moved-from `Observability` object is also blocking
65   // since it flushes the observability data to GCP.
66   //
67   // As an implementation detail, this properly initializes the OpenCensus stats
68   // and tracing plugin, so applications do not need to perform any additional
69   // gRPC C++ OpenCensus setup/registration to get GCP Observability for gRPC.
70   static absl::StatusOr<GcpObservability> Init() GRPC_MUST_USE_RESULT;
71 
72   GcpObservability() = default;
73   // Move constructor and Move-assignment operator.
74   // The moved-from object will no longer be valid and will not cause GCP
75   // Observability stats, tracing and logging data to flush.
76   GcpObservability(GcpObservability&& other) noexcept;
77   GcpObservability& operator=(GcpObservability&& other) noexcept;
78 
79   // Delete copy and copy-assignment operator
80   GcpObservability(const GcpObservability&) = delete;
81   GcpObservability& operator=(const GcpObservability&) = delete;
82 
83  private:
84   // Helper class that aids in implementing GCP Observability.
85   // Inheriting from GrpcLibrary makes sure that gRPC is initialized and remains
86   // initialized for the lifetime of GCP Observability. In the future, when gRPC
87   // initialization goes away, we might still want to keep gRPC Event Engine
88   // initialized, just in case, we need to perform some IO operations during
89   // observability close.
90   // Note that the lifetime guarantees are only one way, i.e., GcpObservability
91   // object guarantees that gRPC will not shutdown while the object is still in
92   // scope, but the other way around does not hold true. Even though that is not
93   // the expected usage, GCP Observability can shutdown before gRPC shuts down.
94   // It follows that gRPC should not hold any callbacks from GcpObservability. A
95   // change in this restriction should go through a design review.
96   class GcpObservabilityImpl : private internal::GrpcLibrary {
97    public:
98     ~GcpObservabilityImpl() override;
99   };
100   std::unique_ptr<GcpObservabilityImpl> impl_;
101 };
102 
103 namespace experimental {
104 // TODO(yashykt): Delete this after the 1.55 release.
105 GRPC_DEPRECATED("Use grpc::GcpObservability::Init() instead.")
106 absl::Status GcpObservabilityInit();
107 GRPC_DEPRECATED("Use grpc::GcpObservability::Init() instead.")
108 void GcpObservabilityClose();
109 }  // namespace experimental
110 
111 }  // namespace grpc
112 
113 #endif  // GRPCPP_EXT_GCP_OBSERVABILITY_H
114