(self, metric_type: str)
Returns a co-routine for writing metrics data.

        :param metric_type: string, must be one of :ref:`Metric Types`
        :raises: ``ValueError`` if the metric type is not one of :ref:`Metric Types`

        To write data timeseries data with the co-routine, call ``send`` with tuples of the form ``(metric_name,
        timestamp, value)``, where

          - ``metric_name`` is a string representing the timeseries name
          - ``timestamp`` is an integer representing epoch seconds
          - ``value`` is a numeric value of the timeseries at timestamp (optionally, this can be a dictionary with
            multiple datapoints at a single timestamp)

        For example::

            with get_writer(...) as writer:
                writer.send(('metric_a', 1501872445, 3))
Returns a co-routine for writing metrics data.
Returns a co - routine for writing metrics data .
def get_writer(self, metric_type: str):
        """ Returns a co-routine for writing metrics data.

        :param metric_type: string, must be one of :ref:`Metric Types`
        :raises: ``ValueError`` if the metric type is not one of :ref:`Metric Types`

        To write data timeseries data with the co-routine, call ``send`` with tuples of the form ``(metric_name,
        timestamp, value)``, where

          - ``metric_name`` is a string representing the timeseries name
          - ``timestamp`` is an integer representing epoch seconds
          - ``value`` is a numeric value of the timeseries at timestamp (optionally, this can be a dictionary with
            multiple datapoints at a single timestamp)

        For example::

            with get_writer(...) as writer:
                writer.send(('metric_a', 1501872445, 3))

        """
        key_prefix = self._get_key_prefix(metric_type)
        table_name = self._get_table_name(metric_type)
        table = self.ddb.Table(table_name)

        def write_batch(self):
            with table.batch_writer() as batch:
                while True:
                    (metric_name, timestamp, value) = yield

                    metric_key = key_prefix + metric_name
                    timestamp = int(timestamp)
                    # these keys should be included in RESERVED_KEYS
                    item = {
                        "key": metric_key,
                        "timestamp": timestamp,
                    }

                    # We only support regex metric requirements for application metrics, so
                    # don't pollute the other tables with useless keys
                    if metric_type == APP_METRICS:
                        item.update(
                            {GSI_PK: random.randrange(_GSI_PARTITIONS), GSI_SORT: key_prefix + str(timestamp),}
                        )
                    if self.ttl_seconds is not None:
                        item["expiration_timestamp"] = timestamp + self.ttl_seconds

                    # Only numeric values (int, float, Decimal, or numeric string) are valid,
                    # or a dict of numeric values for metadata.
                    # Convert to Decimal because DynamoDB only accepts Decimal instead of floats,
                    # and meteorite doesn't like numeric strings.
                    #
                    # TODO (CLUSTERMAN-115) split out the dictionary writer to a separate function
                    if metric_type == METADATA and isinstance(value, dict):
                        for val_key, val_num in value.items():
                            if val_key not in RESERVED_KEYS:
                                item[val_key] = convert_decimal(val_num)
                            else:
                                logger.warning(
                                    'Column "{name}" is reserved; skipping "{name}" with value '
                                    '"{val}" in metric "{key}" at time {ts}'.format(
                                        name=val_key, val=val_num, key=metric_key, ts=timestamp,
                                    )
                                )
                    else:
                        value = convert_decimal(value)
                        item["value"] = value

                    batch.put_item(Item=item)

        coroutine = write_batch(self)
        try:
            next(coroutine)
            yield coroutine
        finally:
            coroutine.close()
def get_writer ( self , metric_type : str ) : key_prefix = self . _get_key_prefix ( metric_type ) table_name = self . _get_table_name ( metric_type ) table = self . ddb . Table ( table_name ) def write_batch ( self ) : with table . batch_writer ( ) as batch : while True : ( metric_name , timestamp , value ) = yield metric_key = key_prefix + metric_name timestamp = int ( timestamp ) # these keys should be included in RESERVED_KEYS item = { "key" : metric_key , "timestamp" : timestamp , } # We only support regex metric requirements for application metrics, so # don't pollute the other tables with useless keys if metric_type == APP_METRICS : item . update ( { GSI_PK : random . randrange ( _GSI_PARTITIONS ) , GSI_SORT : key_prefix + str ( timestamp ) , } ) if self . ttl_seconds is not None : item [ "expiration_timestamp" ] = timestamp + self . ttl_seconds # Only numeric values (int, float, Decimal, or numeric string) are valid, # or a dict of numeric values for metadata. # Convert to Decimal because DynamoDB only accepts Decimal instead of floats, # and meteorite doesn't like numeric strings. # # TODO (CLUSTERMAN-115) split out the dictionary writer to a separate function if metric_type == METADATA and isinstance ( value , dict ) : for val_key , val_num in value . items ( ) : if val_key not in RESERVED_KEYS : item [ val_key ] = convert_decimal ( val_num ) else : logger . warning ( 'Column "{name}" is reserved; skipping "{name}" with value ' '"{val}" in metric "{key}" at time {ts}' . format ( name = val_key , val = val_num , key = metric_key , ts = timestamp , ) ) else : value = convert_decimal ( value ) item [ "value" ] = value batch . put_item ( Item = item ) coroutine = write_batch ( self ) try : next ( coroutine ) yield coroutine finally : coroutine . close ( )