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