sstore_data_attach(3sstore) 맨 페이지 - 윈디하나의 솔라나라

개요

섹션
맨 페이지 이름
검색(S)

sstore_data_attach(3sstore)

Solaris Statistics Store Library Functions
                                                   sstore_data_attach(3SSTORE)



NAME
       sstore_data_attach,  sstore_data_attach_histogram,  sstore_data_update,
       sstore_data_alloc,         sstore_data_free,         sstore_data_reset,
       sstore_data_bulk_update - provide statistics to sstored

SYNOPSIS
            cc [ flag... ] file... -lsstore [ library... ]

                   #include <libsstore.h>

                   typedef struct sstore_data *sstore_data_t;

                   sstore_err_t sstore_data_attach(sstore_handle_t hdl,
                       const char **ids, uint32_t id_count, uint64_t **addrs);

                   sstore_err_t sstore_data_attach_histogram(sstore_handle_t hdl,
                       const char *id, sstore_histogram_t hist);

                   sstore_err_t sstore_data_update(sstore_handle_t hdl,
                        const char **ids, uint32_t id_count,
                        sstore_value_t *vals);

                   sstore_data_t sstore_data_alloc(void);

                   void sstore_data_free(sstore_data_t data);

                   void sstore_data_reset(sstore_data_t data);

                   sstore_err_t sstore_data_add(sstore_handle_t hdl,
                       sstore_data_t data, uint64_t ts,
                       sstore_value_t val);

                   sstore_err_t sstore_data_bulk_update(sstore_handle_t hdl,
                       const char **ids, uint32_t id_count,
                       sstore_data_t *data_arr);

PARAMETERS
       hdl         Handle to libsstore


       ids         Array of statistics store identifiers


       id_count    Total number of statistics store identifiers


       id          Statistic store identifier associated with the histogram


       hist        sstore_histogram_t to be memory-mapped


       vals        Array  of  values  corresponding to the array of statistics
                   store identifiers


       addrs       Address to store the starting address of the  shared-memory
                   region in the statistics store daemon


       data        sstore_data_t containing the data points for a statistic


       ts          Timestamp in microseconds since epoch


       val         Value for a statistic at a given timestamp


       data_arr    Array of sstore_data_t's corresponding to the array of sta‐
                   tistics store identifiers



DESCRIPTION
       The statistics store provides three methods of updating statistics from
       a  user  application:  sstore_data_attach(),  sstore_data_update(), and
       sstore_data_bulk_update().


       The sstore_data_attach() function is an init routine  for  counter-type
       numeric   statistics  that  sets  up  a  shared-memory  region  between
       sstored(8) and the client process. Only one call to  this  function  is
       necessary  during  the runtime of a client process, after which updates
       to the stats can be made directly within the shared-memory region.


       The sstore_data_attach() function performs the following tasks:

           o      Sets up an array of  uint64_t  shared  between  the  calling
                  process and the sstored daemon.


           o      Stores the starting address of this shared array in addrs on
                  success.


           o      Enables any resources in the given  ssid  that  are  defined
                  statically  and are not currently enabled. For more informa‐
                  tion about statically defined resources, see  the  sstore(7)
                  man pages.


           o      Marks statistics in the given ssids as actively provided.



       An  ssid  at  index  i in the ids array maps to the i'th element in the
       addrs array.


       For example, to update the value of ids[i] with val:


       addrs[i] = val;


       The sstore_data_attach_histogram(), like the sstore_data_attach() func‐
       tion,  sets up a shared-memory region between sstored(8) and the client
       process. However, instead of mapping a single counter per statistic, it
       maps  an  array  of  counters corresponding to the buckets in the given
       histogram. The sstore_histogram_t can then be updated using sstore_his‐
       togram_quantize(3SSTORE)  and  the  relevant counter will be updated in
       the shared memory region.


       Note that simply updating the  values  does  not  have  any  impact  on
       sstored(8),  and  these values are not actually sampled until asked for
       either through sstore_data_read(3SSTORE) or sstore(1). For more  infor‐
       mation, see the sstore_data_read(3SSTORE) man page for a description of
       what trigger data capture in the daemon.


       Once capture begins, however, sstore attempts to read from the  shared-
       memory  region  every  second  regardless  of  how quickly the provider
       updates the value.


       Statistics that are  updated  using  the  shared-memory  method  remain
       mapped  by  the statistics store daemon until the client either dies or
       frees the libsstore handle that was used  in  the  sstore_data_attach()
       call.  If  the  client  restarts, then the client must reinitialize the
       shared memory region with the same statistic ordering as before  to  be
       able  to  provide  the statistics again. If the client does not use the
       same ordering, then the call to the sstore_data_attach() function  will
       fail.  If the statistics store daemon restarts but the client does not,
       the client does not need to reinitialize the shared-memory region.


       The sstore_data_update() function allows  users  to  update  values  of
       their  application  statistics for all types of data. This interface is
       provided for string or other large data types that cannot be written to
       shared-memory safely without some additional synchronization mechanism.
       An sstore_data_update() call must be made each time the client wants  a
       value update.


       The sstore_data_update() function performs the following tasks:

           o      Updates  the value of the given ssids with the given values.
                  There is a one to one relationship between the ssids in  ids
                  and the values in data.


           o      Enables  any  resources  in  the given ssid that are defined
                  statically and are not currently enabled. See the  sstore(7)
                  man page for information about statically defined resources.


           o      Marks statistics in the given ssids as actively provided.



       The sstore_data_bulk_update() function allows users to provide multiple
       data points, that is, a set of (timestamp, value) pairs for a statistic
       at  once.  This removes the requirement of providing statistics in real
       time since the user can provide the timestamp  along  with  the  value.
       However,  the  data  points provided must be in chronological order and
       hence the client can only provide data points that are more recent than
       data  points  that  were provided earlier. Any data point that does not
       meet the above requirement will be ignored.


       Any statistic for which data will be provided using this interface also
       needs  to  define "min-update-interval", which is the minimum number of
       seconds between two bulk updates, in its metadata. This field is just a
       pass-through  interface  for  the  consumers  like webui(), to set some
       expectations about the update frequency of a statistic. For more infor‐
       mation, see the webui(7) man page.


       The sstore_data_bulk_update() function performs the following tasks:

           o      Enables  any  resources  in  the given ssid that are defined
                  statically and are not currently enabled. For more  informa‐
                  tion  about statically defined resources, see the sstore(7))
                  man pages.



       Sampling     behavior     for     the     sstore_data_update()      and
       sstore_data_bulk_update()    functions    are    identical    to    the
       sstore_data_attach()  function.  Most  importantly,  values  are   only
       recorded when asked for by the sstore_data_read() function or when per‐
       sistently enabled.  Once  it  starts  recording,  a  statistic  updated
       through  the sstore_data_update() function will be sampled every second
       using the value received in the most recent  update  as  opposed  to  a
       statistic  updated through the sstore_data_bulk_update() function which
       will be sampled as the  new  data  points  become  available  from  the
       statistic provider. For more information on the sampling behaviour, see
       the sstore_data_read(3SSTORE) man page.


       The sstore_data_t is used to provide one or  more  data  points  for  a
       statistic using the sstore_data_bulk_update() function.


       The    sstore_data_alloc()    function   allocates   and   returns   an
       sstore_data_t.


       The sstore_data_free()function frees the given  sstore_data_t  and  all
       the data points stored in it.


       The  sstore_data_reset()  function  frees all the data points stored in
       sstore_data_t and resets it back the state when it  was  alloc'd.  This
       interface  allows  the  client to reuse an sstore_date_t for subsequent
       calls to sstore_data_bulk_update() function.


       The sstore_data_add() function adds a new data point, a timestamp and a
       value, to sstore_data_t. The data points must be added in chronological
       order. The sstore_data_add() function makes a copy of the given val, so
       it can be reused for the next data point.

AUTHORIZATIONS
       For  a description on the authorizations required to provide and update
       statistics, see the sstore-security(7) man page.

RETURN VALUES
       Upon     successful     completion,      sstore_data_update(),      and
       sstore_data_attach() return ESSTORE_OK. Otherwise, they return an error
       code, which is cached in the given libsstore handle.

ERRORS
       The sstore_data_update() and sstore_data_attach() functions fail if:


       ESSTORE_NOMEM                No memory is available


       ESSTORE_ARG_INVALID          One of the following reasons:

                                        o      Required arguments are missing


                                        o      Metadata is not available


                                        o      A provider already  exists  for
                                               at least one of the ssids


                                        o      The  data  type  does not match
                                               the metadata


                                        o      An ssid is invalid


                                        o      An ssid contains a wildcard  or
                                               slice


                                        o      An  ssid  is  not  a user space
                                               statistic or event



       ESSTORE_HANDLE_INVALID       The handle is invalid


       ESSTORE_RETRY                The statistics store daemon is busy. Retry
                                    later


       ESSTORE_CONNECTION_FAILED    Failed  to connect to the statistics store
                                    daemon


       ESSTORE_UNAUTHORIZED         The caller is  not  authorized.  For  more
                                    information,  see  the  sstore-security(7)
                                    man page




       The sstore_data_add() function fails if:


       ESSOTE_ARG_INVALID    One of the following reasons:

                                 o      Required arguments are missing


                                 o      Data point  is  not  in  chronological
                                        order


                                 o      Data  point  value  does not have same
                                        data type as the other data points  in
                                        sstore_data_t




EXAMPLES
       Example 1 Using sstore_data_attach()



       The   following  metadata  files,  installed  in  /usr/lib/sstore/meta‐
       data/json/solaris, are required for this example:


           o      class.app.solaris.exapp.json


           o      stat.app.solaris.exapp.stat1.json


           o      stat.app.solaris.exapp.stat2.json




       After  installing  the  files,   svc:/system/sstore:default   must   be
       restarted.



              class.app.solaris.exapp.json:

              {
                 "$schema": "//:class",
                 "description": "Example class",
                 "id": "app/solaris/exapp",
                 "namespaces": [
                     {
                         "name-type": "string",
                         "resource-name": "name"
                     }
                 ],
                 "stability": "stable",
                 "static-instances": [
                     {
                         "name": "exapp/ins",
                         "namespace": "name"
                     }
                 ],
                 "stat-names": [
                     "//:stat.stat1",
                     "//:stat.stat2"
                 ]
              }

              stat.app.solaris.exapp.stat1.json:

              {
                 "$schema": "//:stat",
                 "description": "Example count statistic one",
                 "id": "//:class.app/solaris/exapp//:stat.stat1",
                 "stability": "stable",
                 "type": "counter",
                 "units": "calls"
              }

              stat.app.solaris.exapp.stat2.json:

              {
                  "$schema": "//:stat",
                  "description": "Example count statistic one",
                  "id": "//:class.app/solaris/exapp//:stat.stat2",
                  "stability": "stable",
                  "type": "counter",
                  "units": "calls"
              }

              The example program, attach_example.c:

              /*
               * Program to provide statistics values
               */
              #include <libsstore.h>
              #include <stdio.h>
              #include <unistd.h>
              #include <stdlib.h>
              #include <fcntl.h>
              #include <sys/stat.h>
              #include <sys/types.h>

              /* libsstore handle */
              sstore_handle_t hdl;

              /* statistic identifiers */
              char *ids[] = {
                      "//:class.app/solaris/exapp//:res.name/exapp/ins//:stat.stat1",
                      "//:class.app/solaris/exapp//:res.name/exapp/ins//:stat.stat2"
              };

              /* structure where values are stored */
              struct mystats {
                      uint64_t stat1;
                      uint64_t stat2;
              };

              int main()
              {
                      int iterations = 10;
                      struct mystats *stats;

                      /* Allocate a libsstore handle */
                      if ((hdl = sstore_alloc()) == NULL) {
                              (void) printf("Failed to allocate handle\n");
                              return (-1);
                      }

                      /*
                       * These statistics already have metadata in a common location,
                       * so sstore knows how to create them. sstore_data_attach will
                       * create a shared-memory region between sstore and this program.
                       */
                      if (sstore_data_attach(hdl, (const char **)&ids, 2,
                          (uint64_t **)&stats) != ESSTORE_OK) {
                              (void) fprintf(stderr,
                                  "Received result message\n\t%s\nfrom sstored "
                                  "in sstore_data_attach\n",
                                  sstore_err_description(hdl));
                              return (-1);
                      }

                      /*
                       * Update the values in the structure. The new values will be
                       * stored when sstore reads them.
                       */
                      while (iterations-- > 0) {
                              stats->stat1++;
                              stats->stat2 += 3;
                              sleep(1);
                      }

                      /*
                       * Free the libsstore handle.
                       * The statistics are marked as not being actively provided.
                       */
                      sstore_free(hdl);

                      return (0);
              }

              Compile this program as follows:

              $ cc -o attach_example attach_example.c -lsstore

              Once the stats store has been restarted, run the following
              command in one terminal to observe the effect of running the
              attach_example program in another terminal:

              $ sstore capture //:class.app/solaris/exapp//:*//:*

              The attach_example program must either be run as root, or a
              user with appropriate stats store privileges. See sstore-security(7)
              for a description of the authorizations required to provide
              and update statistics.



       Example 2 Update counter type stats using sstore_data_update()



       The following metadata files must be installed in /usr/lib/sstore/meta‐
       data/json/solaris, are required for this example:


           o      class.example.json


           o      stat.example.json




       After  installing  the  files,   svc:/system/sstore:default   must   be
       restarted.



              class.example.json:

              {
                 "$schema": "//:class",
                 "description": "example class",
                 "id": "example",
                 "stability": "stable",
                 "stat-names": [
                     "//:stat.one",
                     "//:stat.two"
                 ]
              }

              stat.example.json:

              [
                 {
                     "$schema": "//:stat",
                     "description": "example stat one",
                     "id": "//:class.example//:stat.one",
                     "stability": "stable",
                     "type": "counter",
                     "units": "calls"
                 },
                 {
                     "$schema": "//:stat",
                     "description": "example stat two",
                     "id": "//:class.example//:stat.two",
                     "stability": "stable",
                     "type": "counter",
                     "units": "calls"
                 }
              ]

              /*
               * Example program data_update.c:
               */

              #include <stdio.h>
              #include <stdlib.h>
              #include <unistd.h>
              #include <libsstore.h>

              #define NUM_STATS   2

              const char *ssids[NUM_STATS] = {
                  "//:class.example//:stat.one",
                  "//:class.example//:stat.two"
              };

              int main()
              {
                  sstore_handle_t hdl;
                  sstore_value_t vals[NUM_STATS] = {0};
                  int i, j;

                  if ((hdl = sstore_alloc()) == NULL) {
                      fprintf(stderr, "Failed to alloc libsstore handle\n");
                      return (-1);
                  }

                  /* Alloc the sstore_value_t's */
                  for (i = 0; i < NUM_STATS; i++) {
                      if ((vals[i] = sstore_value_alloc()) == NULL) {
                          fprintf(stderr, "Failed to alloc sstore_value_t\n");
                          goto end;
                      }

                      vals[i]->sv_type = SSTORE_VALUE_NUMBER;
                  }

                  /* Update the stats every second */
                  for (i = 0;; i++) {
                      char *id, *desc;

                      for (j = 0; j < NUM_STATS; j++) {
                          vals[j]->sv_value.num += j + 1;
                      }

                      if (sstore_data_update(hdl, ssids, NUM_STATS,
                          vals) != ESSTORE_OK) {
                              fprintf(stderr, "Failed to update stats. "
                                  "Reason: %s\n", sstore_err_description(hdl));
                              break;
                      }

                      /* Check warnings */
                      while (sstore_warning_next(hdl, &id,
                          &desc) != SS_WARN_OK) {
                              fprintf(stderr, "failed to update stat for %s "
                                  "because %s\n", id, desc);
                      }

                      sleep(1);
                  }

              end:
                  for (i = 0; i < NUM_STATS; i++) {
                      sstore_value_free(vals[i]);
                  }

                  sstore_free(hdl);
                  return (0);
              }

              Compile this program as follows:

              $ cc -o data_update -lsstore data_update.c

              Once the sstore has restarted after installing the metadata,
              run 'data_update' as root or as a user with appropriate stats
              store authorizations. See sstore-security(5) for a description
              of the authorizations required to provide and update
              statistics.

              In another terminal, start recording the stats updated via
              data_update as follows:

              $ sstore capture //:class.example//:stat.*

              Sample output:

              $ sstore capture //:class.example//:stat.*
              TIME                VALUE IDENTIFIER
              2016-03-31T13:36:12 6 //:class.example//:stat.one
              2016-03-31T13:36:12 12 //:class.example//:stat.two
              2016-03-31T13:36:13 7 //:class.example//:stat.one
              2016-03-31T13:36:13 14 //:class.example//:stat.two
              2016-03-31T13:36:14 8 //:class.example//:stat.one
              2016-03-31T13:36:14 16 //:class.example//:stat.two



       Example 3 Update partitioned stat using sstore_data_update()



       The   following  metadata  files,  installed  in  /usr/lib/sstore/meta‐
       data/json/solaris, are required for this example:


           o      class.example_partition.json


           o      stat.example_partition.json




       After  installing  the  files,   svc:/system/sstore:default   must   be
       restarted.



              class.example_partition.json:

              {
                 "$schema": "//:class",
                 "description": "example class",
                 "id": "example/partition",
                 "stability": "stable",
                 "stat-names": [
                     "//:stat.one"
                 ]
              }

              stat.example_partition.json

              {
                 "$schema": "//:stat",
                 "description": "example stat one",
                 "id": "//:class.example/partition//:stat.one",
                 "partitions": [
                     "name",
                     "place"
                 ],
                 "stability": "stable",
                 "type": "counter",
                 "units": "calls"
              }

              /*
               * Example program data_update_partition.c:
               */

              #include <stdio.h>
              #include <stdlib.h>
              #include <unistd.h>
              #include <libsstore.h>

              #define NUM_STATS   1
              #define NUM_PARTS   2
              #define NUM_KEYS    3

              const char *ssids[NUM_STATS] = {
                  "//:class.example/partition//:stat.one"
              };

              const char *example_keys[NUM_PARTS][NUM_KEYS] = {
                  { "john", "tom", "bill" },
                  { "home", "work", "party" }
              };

              int
              main()
              {
                  sstore_handle_t hdl;
                  sstore_value_t val = NULL;
                  sstore_partition_t part = NULL;
                  int i, j;

                  if ((hdl = sstore_alloc()) == NULL) {
                      fprintf(stderr, "Failed to alloc libsstore handle\n");
                      return (-1);
                  }

                  /* Alloc sstore_partition_t */
                  if ((part = sstore_partition_alloc(NUM_PARTS)) == NULL) {
                      fprintf(stderr, "Failed to alloc sstore_partition_t\n");
                      goto end;
                  }
                  /* Alloc and init sstore_value_t */
                  if ((val = sstore_value_alloc()) == NULL) {
                      fprintf(stderr, "Failed to alloc sstore_value_t\n");
                      goto end;
                  }

                  val->sv_type = SSTORE_VALUE_PARTITION;
                  val->sv_value.part = part;

                  /* Update the stats every second */
                  for (i = 0;; i++) {
                      char *id, *desc;
                      char *keys[NUM_PARTS] = {0};
                      uint64_t part_val = i;

                      for (j = 0; j < NUM_PARTS; j++) {
                          keys[j] = (char *)example_keys[j][(i + j) % NUM_KEYS];
                      }

                      if (sstore_partition_inc_value(hdl, part, (const char **)keys,
                          part_val) != ESSTORE_OK) {
                          fprintf(stderr, "Failed to increment partition "
                              "value. Reason: %s\n",
                              sstore_err_description(hdl));
                          break;
                      }

                      if (sstore_data_update(hdl, ssids, NUM_STATS,
                          &val) != ESSTORE_OK) {
                          fprintf(stderr, "Failed to update stats. "
                              "Reason: %s\n",
                              sstore_err_description(hdl));
                          break;
                      }

                      /* Check warnings */
                      while (sstore_warning_next(hdl, &id, &desc) != SS_WARN_OK) {
                          fprintf(stderr, "failed to update stat for %s "
                              "because %s\n", id, desc);
                      }

                      sleep(1);
                  }

              end:
                  sstore_partition_free(part);
                  sstore_value_free(val);
                  sstore_free(hdl);
                  return (0);
              }

              Compile this program as follows:

              $ cc -o data_update_partition -lsstore data_update_partition.c

              Once the sstore has restarted after installing the metadata,
              run 'data_update_partition' as root or as a user with appropriate
              stats store authorizations. See sstore-security(5) for a
              description of the authorizations required to provide and update
              statistics.

              In another terminal, start recording the stats updated via
              data_update as follows:

                  sstore capture //:class.example/partition//:stat.one
                  sstore capture //:class.example/partition//:stat.one//:part.name
                  sstore capture //:class.example/partition//:stat.one//:part.place
                  sstore capture "//:class.example/partition//:stat.one//:part.place(party)//:part.name"


              Sample output:

              $ sstore capture //:class.example/partition//:stat.one
              TIME                VALUE IDENTIFIER
              2016-04-11T17:03:27 703.0 //:class.example/partition//:stat.one
              2016-04-11T17:03:28 741.0 //:class.example/partition//:stat.one
              2016-04-11T17:03:29 780.0 //:class.example/partition//:stat.one

              $ sstore capture //:class.example/partition//:stat.one//:part.name
              TIME                VALUE IDENTIFIER
              2016-04-11T17:03:32  //:class.example/partition//:stat.one//:part.name
                                  john: 315.0
                                  tom: 287.0
                                  bill: 301.0

              $ sstore capture //:class.example/partition//:stat.one//:part.place
              TIME                VALUE IDENTIFIER
              2016-04-11T17:03:35  //:class.example/partition//:stat.one//:part.place
                                  work: 360.0
                                  party: 330.0
                                  home: 345.0
              2016-04-11T17:03:36  //:class.example/partition//:stat.one//:part.place
                                  work: 360.0
                                  party: 376.0
                                  home: 345.0

              $ sstore capture "//:class.example/partition//:stat.one//:part.place(party)//:part.name"
              TIME                VALUE IDENTIFIER
              2016-04-11T17:03:52  //:class.example/partition//:stat.one//:part.place(party)//:part.name
                                  tom: 651.0
              2016-04-11T17:03:53  //:class.example/partition//:stat.one//:part.place(party)//:part.name
                                  tom: 651.0



       Example 4 Update counter type stats using sstore_data_bulk_update()



       The   following  metadata  files,  installed  in  /usr/lib/sstore/meta‐
       data/json/solaris, are required for this example:


           o      class.example_bulk.json


           o      stat.example_bulk.json




       After  installing  the  files,   svc:/system/sstore:default   must   be
       restarted.



              class.example_bulk.json:

              {
                 "$schema": "//:class",
                 "description": "example class",
                 "id": "example/bulk",
                 "stability": "stable",
                 "stat-names": [
                     "//:stat.one",
                     "//:stat.two"
                 ]
              }

              stat.example_bulk.json:

              [
                 {
                     "$schema": "//:stat",
                     "description": "example stat one",
                     "id": "//:class.example/bulk//:stat.one",
                     "min-update-interval": 10,
                     "stability": "stable",
                     "type": "counter",
                     "units": "calls"
                 },
                 {
                     "$schema": "//:stat",
                     "description": "example stat two",
                     "id": "//:class.example/bulk//:stat.two",
                     "min-update-interval": 10,
                     "stability": "stable",
                     "type": "counter",
                     "units": "calls"
                 }
              ]

              /*
               * Example program data_bulk_update.c:
               */
              #include <stdio.h>
              #include <stdlib.h>
              #include <unistd.h>
              #include <libsstore.h>

              #define SEC_TO_uSEC(secs)   ((secs)*1000000)

              #define NUM_STATS   2
              #define SLEEP_INTERVAL  10

              const char *ssids[NUM_STATS] = {
                  "//:class.example/bulk//:stat.one",
                  "//:class.example/bulk//:stat.two"
              };

              /*
               * Gets the current timestamp in microseconds since epoch
               */
              uint64_t
              get_current_ts(void)
              {
                  struct timeval tp = {0};

                  (void) gettimeofday(&tp, NULL);
                  return (SEC_TO_uSEC((uint64_t)tp.tv_sec) + ((uint64_t)tp.tv_usec));
              }

              int
              main()
              {
                  sstore_handle_t hdl;
                  sstore_value_t vals[NUM_STATS] = {0};
                  sstore_data_t data[NUM_STATS] = {0};
                  uint64_t now_ts = get_current_ts();
                  int i, j;

                  if ((hdl = sstore_alloc()) == NULL) {
                      fprintf(stderr, "Failed to alloc libsstore handle\n");
                      return (-1);
                  }

                  /* Alloc the sstore_value_t and sstore_data_t's */
                  for (i = 0; i < NUM_STATS; i++) {
                      if ((vals[i] = sstore_value_alloc()) == NULL) {
                          fprintf(stderr, "Failed to alloc sstore_value_t\n");
                          goto end;
                      }

                      vals[i]->sv_type = SSTORE_VALUE_NUMBER;
                      if ((data[i] = sstore_data_alloc()) == NULL) {
                          fprintf(stderr, "Failed to alloc sstore_data_t\n");
                          goto end;
                      }
                  }

                  /*
                   * Bulk update data points for last SLEEP_INTERVAL seconds for
                   * each stat
                   */
                  while (1) {
                      char *id, *desc;
                      uint64_t ts = now_ts - SEC_TO_uSEC(SLEEP_INTERVAL);

                      /* Add data points for each stat */
                      for (i = 0; i < SLEEP_INTERVAL; i++, ts += 1000000) {
                          for (j = 0; j < NUM_STATS; j++) {
                              vals[j]->sv_value.num += i + j + 1;
                              if (sstore_data_add(hdl, data[j], ts,
                                  vals[j]) != ESSTORE_OK) {
                                  fprintf(stderr, "Failed to add "
                                      "data point. Reason %s\n",
                                      sstore_err_description(hdl));
                                  goto end;
                              }
                          }
                      }

                      /* bulk update */
                      if (sstore_data_bulk_update(hdl, ssids, NUM_STATS,
                          data) != ESSTORE_OK) {
                          fprintf(stderr, "Failed to bulk update. "
                              "Reason %s\n",
                              sstore_err_description(hdl));
                          goto end;
                      }

                      /*
                       * Reset sstore_data_t to avoid resending the same data
                       * points again
                       */
                      for (i = 0; i < NUM_STATS; i++) {
                          sstore_data_reset(data[i]);
                      }

                      /* Check warnings */
                      while (sstore_warning_next(hdl, &id, &desc) != SS_WARN_OK) {
                          fprintf(stderr, "failed to bulk update stat for %s "
                              "because %s\n", id, desc);
                      }

                      sleep(SLEEP_INTERVAL);
                      now_ts += SEC_TO_uSEC(SLEEP_INTERVAL);
                  }

              end:
                  for (i = 0; i < NUM_STATS; i++) {
                      sstore_value_free(vals[i]);
                      sstore_data_free(data[i]);
                  }

                  sstore_free(hdl);
                  return (0);
              }


              Compile this program as follows:

              $ cc -o data_bulk_update -lsstore data_bulk_update.c

              Once the sstore has restarted after installing the metadata,
              run 'data_bulk_update' as root or as a user with appropriate stats
              store authorizations. See sstore-security(5) for a description
              of the authorizations required to provide and update
              statistics.

              In another terminal, start recording the stats updated via
              data_bulk_update as follows:

              $ sstore capture //:class.example/bulk//:stat.*

              Sample output:

              $ sstore capture //:class.example/bulk//:stat.* 10
              TIME                VALUE IDENTIFIER
              2016-04-11T17:52:06 220 //:class.example/bulk//:stat.one
              2016-04-11T17:52:06 260 //:class.example/bulk//:stat.two
              2016-04-11T17:52:16 275 //:class.example/bulk//:stat.one
              2016-04-11T17:52:16 325 //:class.example/bulk//:stat.two
              2016-04-11T17:52:26 330 //:class.example/bulk//:stat.one
              2016-04-11T17:52:26 390 //:class.example/bulk//:stat.two



       Example 5 Update partitioned stat using sstore_data_bulk_update()



       The   following  metadata  files,  installed  in  /usr/lib/sstore/meta‐
       data/json/solaris, are required for this example:


           o      class.example_bulk_partition.json


           o      stat.example_bulk_partition.json




       After  installing  the  files,   svc:/system/sstore:default   must   be
       restarted.



              class.example_bulk_partition.json:

              {
                 "$schema": "//:class",
                 "description": "example class",
                 "id": "example/bulk/partition",
                 "stability": "stable",
                 "stat-names": [
                     "//:stat.one"
                 ]
              }

              stat.example_bulk_partition.json

              {
                 "$schema": "//:stat",
                 "description": "example stat one",
                 "id": "//:class.example/bulk/partition//:stat.one",
                 "min-update-interval": 10,
                 "partitions": [
                     "name",
                     "place"
                 ],
                 "stability": "stable",
                 "type": "counter",
                 "units": "calls"
              }

              /*
               * Example program data_bulk_update_partition.c:
               */
              #include <stdio.h>
              #include <stdlib.h>
              #include <unistd.h>
              #include <libsstore.h>

              #define SEC_TO_uSEC(secs)   ((secs)*1000000)

              #define NUM_STATS   1
              #define NUM_PARTS   2
              #define NUM_KEYS    3
              #define SLEEP_INTERVAL  10

              const char *ssids[NUM_STATS] = {
                  "//:class.example/bulk/partition//:stat.one"
              };

              const char *example_keys[NUM_PARTS][NUM_KEYS] = {
                  { "john", "tom", "bill" },
                  { "home", "work", "party" }
              };

              /*
               * Gets the current timestamp in microseconds since epoch
               */
              uint64_t
              get_current_ts(void)
              {
                  struct timeval tp = {0};

                  (void) gettimeofday(&tp, NULL);
                  return (SEC_TO_uSEC((uint64_t)tp.tv_sec) + ((uint64_t)tp.tv_usec));
              }

              int
              main()
              {
                  sstore_handle_t hdl;
                  sstore_data_t data = NULL;
                  sstore_value_t val = NULL;
                  sstore_partition_t part = NULL;
                  uint64_t now_ts = get_current_ts();
                  int i, j;

                  if ((hdl = sstore_alloc()) == NULL) {
                      fprintf(stderr, "Failed to alloc libsstore handle\n");
                      return (-1);
                  }

                  /* Alloc sstore_partition_t */
                  if ((part = sstore_partition_alloc(NUM_PARTS)) == NULL) {
                      fprintf(stderr, "Failed to alloc sstore_partition_t\n");
                      goto end;
                  }

                  /* Alloc sstore_data_t */
                  if ((data = sstore_data_alloc()) == NULL) {
                      fprintf(stderr, "Failed to alloc sstore_data_t\n");
                      goto end;
                  }

                  /* Alloc and init sstore_value_t */
                  if ((val = sstore_value_alloc()) == NULL) {
                      fprintf(stderr, "Failed to alloc sstore_value_t\n");
                      goto end;
                  }

                  val->sv_type = SSTORE_VALUE_PARTITION;
                  val->sv_value.part = part;

                  /* bulk update the stat */
                  while (1) {
                      char *id, *desc;
                      char *keys[NUM_PARTS] = {0};
                      uint64_t ts = now_ts - SEC_TO_uSEC(SLEEP_INTERVAL);

                      /* Add data points for the last SLEEP_INTERVAL seconds */
                      for (i = 0; i < SLEEP_INTERVAL; i++, ts += 1000000) {
                          uint64_t part_val = i;

                          for (j = 0; j < NUM_PARTS; j++) {
                              keys[j] = (char *)example_keys[j][(i + j) % NUM_KEYS];
                          }

                          if (sstore_partition_inc_value(hdl, part, (const char **)keys,
                              part_val) != ESSTORE_OK) {
                              fprintf(stderr, "Failed to increment partition "
                                  "value. Reason: %s\n",
                                  sstore_err_description(hdl));
                              break;
                          }

                          if (sstore_data_add(hdl, data, ts, val) != ESSTORE_OK) {
                              fprintf(stderr, "Failed to add data point. "
                                  "Reason %s\n",
                                  sstore_err_description(hdl));
                              goto end;
                          }
                      }

                      /* bulk update */
                      if (sstore_data_bulk_update(hdl, ssids, NUM_STATS,
                          &data) != ESSTORE_OK) {
                          fprintf(stderr, "Failed to bulk update stat. "
                              "Reason: %s\n",
                              sstore_err_description(hdl));
                          break;
                      }

                      /*
                       * Reset sstore_data_t to avoid resending the same data
                       * points again
                       */
                      sstore_data_reset(data);

                      /* Check warnings */
                      while (sstore_warning_next(hdl, &id, &desc) != SS_WARN_OK) {
                          fprintf(stderr, "failed to bulk update stat %s "
                              "because %s\n", id, desc);
                      }

                      sleep(SLEEP_INTERVAL);
                      now_ts += SEC_TO_uSEC(SLEEP_INTERVAL);
                  }

              end:
                  sstore_partition_free(part);
                  sstore_value_free(val);
                  sstore_data_free(data);
                  sstore_free(hdl);
                  return (0);
              }


              Compile this program as follows:

              $ cc -o data_bulk_update_partition -lsstore data_bulk_update_partition.c

              Once the sstore has restarted after installing the metadata,
              run 'data_bulk_update_partition' as root or as a user with appropriate
              stats store authorizations. See sstore-security(5) for a
              description of the authorizations required to provide and update
              statistics.

              In another terminal, start recording the stats updated via
              data_bulk_update as follows:

                  sstore capture //:class.example/bulk/partition//:stat.one 10
                  sstore capture //:class.example/bulk/partition//:stat.one//:part.name 10
                  sstore capture //:class.example/bulk/partition//:stat.one//:part.place 10

              Sample output:

              $ sstore capture //:class.example/partition//:stat.one 10
              TIME                VALUE IDENTIFIER
              2016-04-11T18:10:40 180.0 //:class.example/bulk/partition//:stat.one
              2016-04-11T18:10:50 225.0 //:class.example/bulk/partition//:stat.one

              $ sstore capture //:class.example/partition//:stat.one//:part.name 10
              TIME                VALUE IDENTIFIER
              2016-04-11T18:10:50  //:class.example/bulk/partition//:stat.one//:part.name
                                  john: 90.0
                                  tom: 60.0
                                  bill: 75.0
              2016-04-11T18:10:50  //:class.example/bulk/partition//:stat.one//:part.name
                                  john: 90.0
                                  tom: 60.0
                                  bill: 75.0

              $ sstore capture //:class.example/partition//:stat.one//:part.place 10
              TIME                VALUE IDENTIFIER
              2016-04-11T18:12:35  //:class.example/partition//:stat.one//:part.place
                                  work: 252.0
                                  party: 168.0
                                  home: 210.0
              2016-04-11T18:12:45  //:class.example/partition//:stat.one//:part.place
                                  work: 270.0
                                  party: 180.0
                                  home: 225.0




ATTRIBUTES
       See attributes(7) for descriptions of the following attributes:


       tab()  box; cw(2.75i) |cw(2.75i) lw(2.75i) |lw(2.75i) ATTRIBUTE TYPEAT‐
       TRIBUTE VALUE _ Availabilitypkg:/service/system/sstore _ Interface Sta‐
       bilityCommitted _ MT-LevelSafe


SEE ALSO
       libnvpair(3LIB),         libsstore(3LIB),        sstore_alloc(3SSTORE),
       sstore_data_read(3SSTORE),                  sstore_err_action(3SSTORE),
       sstore_range_alloc(3SSTORE),  attributes(7),  privileges(7), sstore(7),
       sstore-security(7)



Oracle Solaris 11.4               27 Nov 2017
                                                   sstore_data_attach(3SSTORE)
맨 페이지 내용의 저작권은 맨 페이지 작성자에게 있습니다.
RSS ATOM XHTML 5 CSS3