< Summary

Information
Class: IceMX.MetricsHelper<T>
Assembly: Ice
File(s): /home/runner/work/ice/ice/csharp/src/Ice/MetricsObserverI.cs
Tag: 71_18251537082
Line coverage
100%
Covered lines: 4
Uncovered lines: 0
Coverable lines: 4
Total lines: 440
Line coverage: 100%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage
100%
Covered methods: 4
Total methods: 4
Method coverage: 100%

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
resolve(...)100%11100%
initMetrics(...)100%11100%
defaultResolve(...)100%11100%

File(s)

/home/runner/work/ice/ice/csharp/src/Ice/MetricsObserverI.cs

#LineLine coverage
 1// Copyright (c) ZeroC, Inc.
 2
 3using Ice.Internal;
 4using System.Diagnostics;
 5
 6namespace IceMX;
 7
 8public class MetricsHelper<T> where T : Metrics
 9{
 10    public class AttributeResolver
 11    {
 12        private abstract class Resolver
 13        {
 14            protected Resolver(string name) => _name = name;
 15
 16            protected abstract object resolve(object obj);
 17
 18            public string resolveImpl(object obj)
 19            {
 20                try
 21                {
 22                    object result = resolve(obj);
 23                    if (result != null)
 24                    {
 25                        return result.ToString();
 26                    }
 27                    return "";
 28                }
 29                catch (ArgumentOutOfRangeException)
 30                {
 31                    throw;
 32                }
 33                catch (Exception ex)
 34                {
 35                    throw new ArgumentOutOfRangeException(_name, ex);
 36                }
 37            }
 38
 39            protected object getField(System.Reflection.FieldInfo field, object obj)
 40            {
 41                while (obj != null)
 42                {
 43                    try
 44                    {
 45                        return field.GetValue(obj);
 46                    }
 47                    catch (ArgumentException)
 48                    {
 49                        if (obj is Ice.EndpointInfo)
 50                        {
 51                            obj = ((Ice.EndpointInfo)obj).underlying;
 52                        }
 53                        else if (obj is Ice.ConnectionInfo)
 54                        {
 55                            obj = ((Ice.ConnectionInfo)obj).underlying;
 56                        }
 57                        else
 58                        {
 59                            throw;
 60                        }
 61                    }
 62                }
 63                return null;
 64            }
 65
 66            protected object getProperty(System.Reflection.PropertyInfo property, object obj) =>
 67                property?.GetValue(obj);
 68
 69            protected readonly string _name;
 70        }
 71
 72        private class FieldResolverI : Resolver
 73        {
 74            internal FieldResolverI(string name, System.Reflection.FieldInfo field)
 75                : base(name)
 76            {
 77                Debug.Assert(field != null);
 78                _field = field;
 79            }
 80
 81            protected override object resolve(object obj) => getField(_field, obj);
 82
 83            private readonly System.Reflection.FieldInfo _field;
 84        }
 85
 86        private class MethodResolverI : Resolver
 87        {
 88            internal MethodResolverI(string name, System.Reflection.MethodInfo method)
 89                : base(name)
 90            {
 91                Debug.Assert(method != null);
 92                _method = method;
 93            }
 94
 95            protected override object resolve(object obj) => _method.Invoke(obj, null);
 96
 97            private readonly System.Reflection.MethodInfo _method;
 98        }
 99
 100        private class MemberFieldResolverI : Resolver
 101        {
 102            internal MemberFieldResolverI(
 103                string name,
 104                System.Reflection.MethodInfo method,
 105                System.Reflection.FieldInfo field)
 106                : base(name)
 107            {
 108                Debug.Assert(method != null && field != null);
 109                _method = method;
 110                _field = field;
 111            }
 112
 113            protected override object resolve(object obj)
 114            {
 115                object o = _method.Invoke(obj, null);
 116                if (o != null)
 117                {
 118                    return getField(_field, o);
 119                }
 120                throw new ArgumentOutOfRangeException(_name);
 121            }
 122
 123            private readonly System.Reflection.MethodInfo _method;
 124            private readonly System.Reflection.FieldInfo _field;
 125        }
 126
 127        private class MemberPropertyResolverI : Resolver
 128        {
 129            private readonly System.Reflection.MethodInfo _method;
 130            private readonly System.Reflection.PropertyInfo _property;
 131
 132            internal MemberPropertyResolverI(
 133                string name,
 134                System.Reflection.MethodInfo method,
 135                System.Reflection.PropertyInfo property)
 136                : base(name)
 137            {
 138                Debug.Assert(method is not null && property is not null);
 139                _method = method;
 140                _property = property;
 141            }
 142
 143            protected override object resolve(object obj) =>
 144                _method.Invoke(obj, null) is object o ?
 145                    getProperty(_property, o) : throw new ArgumentOutOfRangeException(_name);
 146        }
 147
 148        private class MemberMethodResolverI : Resolver
 149        {
 150            internal MemberMethodResolverI(
 151                string name,
 152                System.Reflection.MethodInfo method,
 153                System.Reflection.MethodInfo subMeth)
 154                : base(name)
 155            {
 156                Debug.Assert(method != null && subMeth != null);
 157                _method = method;
 158                _subMethod = subMeth;
 159            }
 160
 161            protected override object resolve(object obj)
 162            {
 163                object o = _method.Invoke(obj, null);
 164                if (o != null)
 165                {
 166                    return _subMethod.Invoke(o, null);
 167                }
 168                throw new ArgumentOutOfRangeException(_name);
 169            }
 170
 171            private readonly System.Reflection.MethodInfo _method;
 172            private readonly System.Reflection.MethodInfo _subMethod;
 173        }
 174
 175        protected AttributeResolver()
 176        {
 177        }
 178
 179        public string resolve(MetricsHelper<T> helper, string attribute)
 180        {
 181            if (!_attributes.TryGetValue(attribute, out Resolver resolver))
 182            {
 183                if (attribute == "none")
 184                {
 185                    return "";
 186                }
 187                string v = helper.defaultResolve(attribute);
 188                if (v != null)
 189                {
 190                    return v;
 191                }
 192                throw new ArgumentOutOfRangeException(attribute);
 193            }
 194            return resolver.resolveImpl(helper);
 195        }
 196
 197        public void add(
 198            string name,
 199            System.Reflection.MethodInfo method) => _attributes.Add(name, new MethodResolverI(name, method));
 200
 201        public void add(
 202            string name,
 203            System.Reflection.FieldInfo field) => _attributes.Add(name, new FieldResolverI(name, field));
 204
 205        public void add(
 206            string name,
 207            System.Reflection.MethodInfo method,
 208            System.Reflection.FieldInfo field) =>
 209                _attributes.Add(name, new MemberFieldResolverI(name, method, field));
 210
 211        public void add(
 212            string name,
 213            System.Reflection.MethodInfo method,
 214            System.Reflection.PropertyInfo property) =>
 215      _attributes.Add(name, new MemberPropertyResolverI(name, method, property));
 216
 217        public void
 218        add(
 219            string name,
 220            System.Reflection.MethodInfo method,
 221            System.Reflection.MethodInfo subMethod) =>
 222                _attributes.Add(name, new MemberMethodResolverI(name, method, subMethod));
 223
 224        private readonly Dictionary<string, Resolver> _attributes = new Dictionary<string, Resolver>();
 225    }
 226
 1227    protected MetricsHelper(AttributeResolver attributes) => _attributes = attributes;
 228
 1229    public string resolve(string attribute) => _attributes.resolve(this, attribute);
 230
 231    public virtual void initMetrics(T metrics)
 232    {
 233        // Override in specialized helpers.
 1234    }
 235
 1236    protected virtual string defaultResolve(string attribute) => null;
 237
 238    private readonly AttributeResolver _attributes;
 239}
 240
 241public class Observer<T> : Stopwatch, Ice.Instrumentation.Observer where T : Metrics, new()
 242{
 243    public delegate void MetricsUpdate(T m);
 244
 245    public virtual void attach() => Start();
 246
 247    public virtual void detach()
 248    {
 249        Stop();
 250        long lifetime = _previousDelay + (long)(ElapsedTicks / (Frequency / 1000000.0));
 251        foreach (MetricsMap<T>.Entry e in _objects)
 252        {
 253            e.detach(lifetime);
 254        }
 255    }
 256
 257    public virtual void failed(string exceptionName)
 258    {
 259        foreach (MetricsMap<T>.Entry e in _objects)
 260        {
 261            e.failed(exceptionName);
 262        }
 263    }
 264
 265    public void forEach(MetricsUpdate u)
 266    {
 267        foreach (MetricsMap<T>.Entry e in _objects)
 268        {
 269            e.execute(u);
 270        }
 271    }
 272
 273    public void init(MetricsHelper<T> helper, List<MetricsMap<T>.Entry> objects, Observer<T> previous)
 274    {
 275        _objects = objects;
 276
 277        if (previous == null)
 278        {
 279            return;
 280        }
 281
 282        _previousDelay = previous._previousDelay + (long)(previous.ElapsedTicks / (Frequency / 1000000.0));
 283        foreach (MetricsMap<T>.Entry e in previous._objects)
 284        {
 285            if (!_objects.Contains(e))
 286            {
 287                e.detach(_previousDelay);
 288            }
 289        }
 290    }
 291
 292    public ObserverImpl getObserver<S, ObserverImpl>(string mapName, MetricsHelper<S> helper)
 293        where S : Metrics, new()
 294        where ObserverImpl : Observer<S>, new()
 295    {
 296        List<MetricsMap<S>.Entry> metricsObjects = null;
 297        foreach (MetricsMap<T>.Entry entry in _objects)
 298        {
 299            MetricsMap<S>.Entry e = entry.getMatching(mapName, helper);
 300            if (e != null)
 301            {
 302                metricsObjects ??= new List<MetricsMap<S>.Entry>(_objects.Count);
 303                metricsObjects.Add(e);
 304            }
 305        }
 306
 307        if (metricsObjects == null)
 308        {
 309            return null;
 310        }
 311
 312        try
 313        {
 314            var obsv = new ObserverImpl();
 315            obsv.init(helper, metricsObjects, null);
 316            return obsv;
 317        }
 318        catch (Exception)
 319        {
 320            Debug.Assert(false);
 321            return null;
 322        }
 323    }
 324
 325    public MetricsMap<T>.Entry getEntry(MetricsMap<T> map)
 326    {
 327        foreach (MetricsMap<T>.Entry e in _objects)
 328        {
 329            if (e.getMap() == map)
 330            {
 331                return e;
 332            }
 333        }
 334        return null;
 335    }
 336
 337    private List<MetricsMap<T>.Entry> _objects;
 338    private long _previousDelay;
 339}
 340
 341public class ObserverFactory<T, O> where T : Metrics, new() where O : Observer<T>, new()
 342{
 343    public ObserverFactory(Ice.Internal.MetricsAdminI metrics, string name)
 344    {
 345        _metrics = metrics;
 346        _name = name;
 347        _metrics.registerMap<T>(name, this.update);
 348    }
 349
 350    public ObserverFactory(string name)
 351    {
 352        _name = name;
 353        _metrics = null;
 354    }
 355
 356    public void destroy() => _metrics?.unregisterMap(_name);
 357
 358    public O getObserver(MetricsHelper<T> helper) => getObserver(helper, null);
 359
 360    public O getObserver(MetricsHelper<T> helper, object observer)
 361    {
 362        lock (_mutex)
 363        {
 364            List<MetricsMap<T>.Entry> metricsObjects = null;
 365            O old = null;
 366            try
 367            {
 368                old = (O)observer;
 369            }
 370            catch (InvalidCastException)
 371            {
 372            }
 373            foreach (MetricsMap<T> m in _maps)
 374            {
 375                MetricsMap<T>.Entry e = m.getMatching(helper, old?.getEntry(m));
 376                if (e != null)
 377                {
 378                    metricsObjects ??= new List<MetricsMap<T>.Entry>(_maps.Count);
 379                    metricsObjects.Add(e);
 380                }
 381            }
 382
 383            if (metricsObjects == null)
 384            {
 385                old?.detach();
 386                return null;
 387            }
 388
 389            O obsv;
 390            try
 391            {
 392                obsv = new O();
 393            }
 394            catch (Exception)
 395            {
 396                Debug.Assert(false);
 397                return null;
 398            }
 399            obsv.init(helper, metricsObjects, old);
 400            return obsv;
 401        }
 402    }
 403
 404    public void registerSubMap<S>(string subMap, System.Reflection.FieldInfo field)
 405        where S : Metrics, new() => _metrics.registerSubMap<S>(_name, subMap, field);
 406
 407    public bool isEnabled() => _enabled;
 408
 409    public void update()
 410    {
 411        Action updater;
 412        lock (_mutex)
 413        {
 414            _maps.Clear();
 415            foreach (MetricsMap<T> m in _metrics.getMaps<T>(_name))
 416            {
 417                _maps.Add(m);
 418            }
 419            _enabled = _maps.Count > 0;
 420            updater = _updater;
 421        }
 422
 423        updater?.Invoke();
 424    }
 425
 426    public void setUpdater(Action updater)
 427    {
 428        lock (_mutex)
 429        {
 430            _updater = updater;
 431        }
 432    }
 433
 434    private readonly MetricsAdminI _metrics;
 435    private readonly string _name;
 436    private readonly List<MetricsMap<T>> _maps = new();
 437    private volatile bool _enabled;
 438    private Action _updater;
 439    private readonly object _mutex = new();
 440}