3 ==================================================================================
4 Copyright (c) 2020 Nokia
5 Copyright (c) 2020 AT&T Intellectual Property.
7 Licensed under the Apache License, Version 2.0 (the "License");
8 you may not use this file except in compliance with the License.
9 You may obtain a copy of the License at
11 http://www.apache.org/licenses/LICENSE-2.0
13 Unless required by applicable law or agreed to in writing, software
14 distributed under the License is distributed on an "AS IS" BASIS,
15 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 See the License for the specific language governing permissions and
17 limitations under the License.
18 ==================================================================================
23 Abstract: Impementation of the metrics functions. (see metrics.hpp)
26 void Set_source( std::string new_source );
27 void Set_reporter( std::string new_reporter );
28 void Push_data( std::string key, double value );
31 Author: E. Scott Daniels
38 #include <rmr/RIC_message_types.h>
40 #define RIC_METRICS 120
45 #include "msg_component.hpp"
46 #include "message.hpp"
47 #include "metrics.hpp"
49 extern char* __progname; // runtime lib supplied since we don't get argv[0]
57 // ------ private ----------------------------------------------
61 Return the current time in milliseconds past the UNIX epoch.
63 static long long now( void ) {
67 clock_gettime( CLOCK_REALTIME, &ts );
68 now = (ts.tv_sec * 1000000) + (ts.tv_nsec/1000000); // convert nano to milli and bang onto seconds
75 Build the payload that we'll send.
76 Accepts a pointer to the payload message component in the RMR message that we are
77 to fill in, along with the maxmimum length of the payload. Returns the length of
78 the payload that was acutally used.
80 Currently, the munchkin expects:
82 "reporter": "<string>",
83 "generator" "<string>",
94 int xapp::Metrics::build_payload( xapp::Msg_component payload, int max_len ) {
95 int used; // actual size of payload created
96 std::string generator;
99 if( data.compare( "" ) == 0 ) { // xAPP never pushed any data
100 return 0; // don't build, just bail
103 generator = source.compare( "" ) == 0 ? reporter : source;
105 used = snprintf( (char *) payload.get(), max_len,
107 "\"reporter\": \"%s\", "
108 "\"generator\": \"%s\", "
109 "\"timestamp\": %lld, "
122 // --------------- builders/operators -------------------------------------
125 Create a new metrics "message" with a provided (empty) RMR message.
127 xapp::Metrics::Metrics( std::shared_ptr<Message> msg ) :
129 reporter( __progname ),
135 Build a metrics for a value source other than the calling xAPP
137 xapp::Metrics::Metrics( std::shared_ptr<Message> msg, std::string msource ) :
139 reporter( __progname ),
145 Build a metrics object that allows the xAPP to set it's reporter name
146 rather than assuming the programme name and the source.
148 The xAPP can pass "" as the msource if the intent is just to supply
149 an alternate programme name which is also the source.
151 xapp::Metrics::Metrics( std::shared_ptr<Message> msg, std::string reporter, std::string msource ) :
153 reporter( reporter ),
158 // ------------------ copy and move support ---------------------------------
161 Copy builder. Given a source object instance (soi), create a copy.
162 Creating a copy should be avoided as it can be SLOW!
164 xapp::Metrics::Metrics( const Metrics& soi ) {
168 reporter = soi.reporter;
172 Assignment operator. Simiolar to the copycat, but "this" object exists and
173 may have data that needs to be released prior to making a copy of the soi.
175 Metrics& xapp::Metrics::operator=( const Metrics& soi ) {
176 if( this != &soi ) { // cannot do self assignment
177 // anything that must be freed from 'this' must be done here
182 reporter = soi.reporter;
189 Move builder. Given a source object instance (soi), move the information from
190 the soi ensuring that the destriction of the soi doesn't trash things from
193 xapp::Metrics::Metrics( Metrics&& soi ) {
194 msg = soi.msg; // capture pointers and copy data before setting soruce things to nil
197 reporter = soi.reporter;
199 soi.msg = NULL; // prevent closing of RMR stuff on soi destroy
203 Move Assignment operator. Move the message data to the existing object
204 ensure the object reference is cleaned up, and ensuring that the source
205 object references are removed.
207 Metrics& xapp::Metrics::operator=( Metrics&& soi ) {
208 if( this != &soi ) { // cannot do self assignment
209 // anything that needs to be freed/delted from 'this', must be done here
211 msg = soi.msg; // move pointers and values
214 reporter = soi.reporter;
216 soi.msg = NULL; // prevent bad things when source is destroyed
225 xapp::Metrics::~Metrics() {
230 // ---- setters -------------------------------------------------
232 void xapp::Metrics::Set_source( std::string new_source ) {
236 void xapp::Metrics::Set_reporter( std::string new_reporter ) {
237 reporter = new_reporter;
241 Pushes the key/value pair onto the current data list.
242 This could be more efficent, but for now it is simple.
244 void xapp::Metrics::Push_data( std::string key, double value ) {
246 char* sep = (char *) " ";
248 if( data.compare( "" ) != 0 ) { // first on the list, no need for preceeding comma
252 snprintf( wbuf, sizeof( wbuf ), "%s{ \"id\": \"%s\", \"value\": %.5f }", sep, key.c_str(), value );
254 data += std::string( wbuf );
257 // ------------------- getters ------------------------------------
260 // ------- message sending ---------------------------------------
263 Send the message by building the payload and passing to RMR.
264 Returns the state of the send (true == good). If the xapp did not
265 push any data, no send is actually invoked, and true is reported.
267 bool xapp::Metrics::Send( ) {
268 int used = 0; // actual num bytes used in the payload
271 used = build_payload( msg->Get_payload(), msg->Get_available_size() - 1 );
273 //fprintf( stderr, ">>>> sending payload: %s\n", (char *) msg->Get_payload().get() );
274 state = msg->Send_msg( RIC_METRICS, RMR_VOID_SUBID, used+1, NULL );
277 data = ""; // clear data after the send