예제 #1
0
        /// <summary>
        /// Use this constructor when instantiating from a field.
        /// </summary>
        public MetricTag(FieldInfo fieldInfo, MetricTagAttribute attribute, Func <string, string> nameReplacer)
        {
            IsFromDefault = false;
            IsOptional    = attribute.IsOptional;

            FieldInfo = fieldInfo;
            if (!FieldInfo.IsInitOnly || (FieldInfo.FieldType != typeof(string) && !FieldInfo.FieldType.IsEnum))
            {
                throw new InvalidOperationException(
                          $"The BosunTag attribute can only be applied to readonly string or enum fields. {fieldInfo.DeclaringType.FullName}.{fieldInfo.Name} is invalid.");
            }

            Attribute = attribute;

            if (attribute.Name != null)
            {
                Name = attribute.Name;
            }
            else if (nameReplacer != null)
            {
                Name = nameReplacer(fieldInfo.Name);
            }
            else
            {
                Name = fieldInfo.Name;
            }

            if (!MetricValidation.IsValidTagName(Name))
            {
                throw new InvalidOperationException($"\"{Name}\" is not a valid Bosun Tag name. Field: {fieldInfo.DeclaringType.FullName}.{fieldInfo.Name}.");
            }
        }
예제 #2
0
        /// <summary>
        /// Use this constructor when instantiating from a field or property.
        /// </summary>
        public MetricTag(MemberInfo memberInfo, MetricTagAttribute attribute, Func <string, string> nameReplacer)
        {
            switch (memberInfo)
            {
            case FieldInfo fieldInfo:
                if (!fieldInfo.IsInitOnly || (fieldInfo.FieldType != typeof(string) && !fieldInfo.FieldType.IsEnum))
                {
                    throw new InvalidOperationException(
                              $"The MetricTag attribute can only be applied to readonly string or enum fields. {memberInfo.DeclaringType.FullName}.{memberInfo.Name} is invalid."
                              );
                }

                break;

            case PropertyInfo propertyInfo:
                if (propertyInfo.SetMethod != null ||
                    (propertyInfo.PropertyType != typeof(string) && !propertyInfo.PropertyType.IsEnum))
                {
                    throw new InvalidOperationException(
                              $"The MetricTag attribute can only be applied to readonly string or enum properties. {memberInfo.DeclaringType.FullName}.{memberInfo.Name} is invalid."
                              );
                }

                break;

            default:
                throw new InvalidOperationException(
                          $"The MetricTag attribute can only be applied to properties or fields. {memberInfo.DeclaringType.FullName}.{memberInfo.Name} is invalid."
                          );
            }

            IsFromDefault = false;
            IsOptional    = attribute.IsOptional;
            MemberInfo    = memberInfo;
            Attribute     = attribute;

            if (attribute.Name != null)
            {
                Name = attribute.Name;
            }
            else if (nameReplacer != null)
            {
                Name = nameReplacer(memberInfo.Name);
            }
            else
            {
                Name = memberInfo.Name;
            }

            if (!MetricValidation.IsValidTagName(Name))
            {
                throw new InvalidOperationException($"\"{Name}\" is not a valid tag name. Field: {memberInfo.DeclaringType.FullName}.{memberInfo.Name}.");
            }
        }
예제 #3
0
        /// <summary>
        /// Applies an <see cref="AggregateMode"/> to an <see cref="AggregateGauge"/>.
        /// </summary>
        /// <param name="mode">The aggregate mode. Don't use AggregateMode.Percentile with this constructor.</param>
        /// <param name="suffix">Overrides the default suffix for the aggregate mode.</param>
        /// <param name="percentile">
        /// The percentile represented as a double. For example, 0.95 = 95th percentile. Using more than two digits is not recommended. In order to use this
        /// argument, <paramref name="mode"/> must be AggregateMode.Percentile.
        /// </param>
        public GaugeAggregatorAttribute(AggregateMode mode, string suffix, double percentile)
        {
            AggregateMode = mode;
            Percentile    = AggregateGauge.AggregateModeToPercentileAndSuffix(mode, percentile, out var defaultSuffix);
            Suffix        = suffix ?? defaultSuffix;

            if (Suffix.Length > 0 && !MetricValidation.IsValidMetricName(Suffix))
            {
                throw new Exception("\"" + Suffix + "\" is not a valid metric suffix.");
            }
        }
예제 #4
0
        internal IReadOnlyDictionary <string, string> GetTags(
            IReadOnlyDictionary <string, string> defaultTags,
            TagValueConverterDelegate tagValueConverter,
            Func <string, string> propertyToTagConverter,
            Dictionary <Type, List <MetricTag> > tagsByTypeCache)
        {
            var tags = new Dictionary <string, string>();

            foreach (var tag in GetTagsList(defaultTags, propertyToTagConverter, tagsByTypeCache))
            {
                var value = tag.IsFromDefault ? defaultTags[tag.Name] : tag.GetValue(this);
                if (tagValueConverter != null)
                {
                    value = tagValueConverter(tag.Name, value);
                }

                if (value == null)
                {
                    if (tag.IsOptional)
                    {
                        continue;
                    }

                    throw new InvalidOperationException(
                              $"null is not a valid tag value for {GetType().FullName}.{tag.MemberInfo.Name}. This tag was declared as non-optional.");
                }
                if (!MetricValidation.IsValidTagValue(value))
                {
                    throw new InvalidOperationException(
                              $"Invalid value for tag {GetType().FullName}.{tag.MemberInfo.Name}. \"{value}\" is not a valid tag value. " +
                              $"Only characters in the regex class [a-zA-Z0-9\\-_./] are allowed.");
                }

                tags.Add(tag.Name, value);
            }

            if (tags.Count == 0)
            {
                throw new InvalidOperationException(
                          $"At least one tag value must be specified for every metric. {GetType().FullName} was instantiated without any tag values.");
            }

            return(tags);
        }