< Summary

Information
Class: Ice.Internal.ConnectionObserverI
Assembly: Ice
File(s): /home/runner/work/ice/ice/csharp/src/Ice/Internal/InstrumentationI.cs
Tag: 71_18251537082
Line coverage
100%
Covered lines: 10
Uncovered lines: 0
Coverable lines: 10
Total lines: 1100
Line coverage: 100%
Branch coverage
100%
Covered branches: 4
Total branches: 4
Branch coverage: 100%
Method coverage
100%
Covered methods: 4
Total methods: 4
Method coverage: 100%

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
sentBytes(...)100%22100%
receivedBytes(...)100%22100%
sentBytesUpdate(...)100%11100%
receivedBytesUpdate(...)100%11100%

File(s)

/home/runner/work/ice/ice/csharp/src/Ice/Internal/InstrumentationI.cs

#LineLine coverage
 1// Copyright (c) ZeroC, Inc.
 2
 3using IceMX;
 4using System.Diagnostics;
 5using System.Text;
 6
 7namespace Ice.Internal;
 8
 9public class ObserverWithDelegate<T, O> : Observer<T>
 10    where T : Metrics, new()
 11    where O : Ice.Instrumentation.Observer
 12{
 13    public override void
 14    attach()
 15    {
 16        base.attach();
 17        delegate_?.attach();
 18    }
 19
 20    public override void
 21    detach()
 22    {
 23        base.detach();
 24        delegate_?.detach();
 25    }
 26
 27    public override void
 28    failed(string exceptionName)
 29    {
 30        base.failed(exceptionName);
 31        delegate_?.failed(exceptionName);
 32    }
 33
 34    public O
 35    getDelegate() => delegate_;
 36
 37    public void
 38    setDelegate(O del) => delegate_ = del;
 39
 40    public Observer getObserver<S, ObserverImpl, Observer>(string mapName, MetricsHelper<S> helper, Observer del)
 41        where S : Metrics, new()
 42        where ObserverImpl : ObserverWithDelegate<S, Observer>, Observer, new()
 43        where Observer : Ice.Instrumentation.Observer
 44    {
 45        ObserverImpl obsv = getObserver<S, ObserverImpl>(mapName, helper);
 46        if (obsv != null)
 47        {
 48            obsv.setDelegate(del);
 49            return obsv;
 50        }
 51        return del;
 52    }
 53
 54    protected O delegate_;
 55}
 56
 57public class ObserverFactoryWithDelegate<T, OImpl, O> : ObserverFactory<T, OImpl>
 58    where T : Metrics, new()
 59    where OImpl : ObserverWithDelegate<T, O>, O, new()
 60    where O : Ice.Instrumentation.Observer
 61{
 62    public ObserverFactoryWithDelegate(MetricsAdminI metrics, string name)
 63        : base(metrics, name)
 64    {
 65    }
 66
 67    public O getObserver(MetricsHelper<T> helper, O del)
 68    {
 69        OImpl o = getObserver(helper);
 70        if (o != null)
 71        {
 72            o.setDelegate(del);
 73            return o;
 74        }
 75        return del;
 76    }
 77
 78    public O getObserver(MetricsHelper<T> helper, object observer, O del)
 79    {
 80        OImpl o = getObserver(helper, observer);
 81        if (o != null)
 82        {
 83            o.setDelegate(del);
 84            return o;
 85        }
 86        return del;
 87    }
 88}
 89
 90internal static class AttrsUtil
 91{
 92    public static void
 93    addEndpointAttributes<T>(MetricsHelper<T>.AttributeResolver r, Type cl) where T : IceMX.Metrics
 94    {
 95        r.add("endpoint", cl.GetMethod("getEndpoint"));
 96
 97        Type cli = typeof(Ice.EndpointInfo);
 98        r.add("endpointType", cl.GetMethod("getEndpointInfo"), cli.GetMethod("type"));
 99        r.add("endpointIsDatagram", cl.GetMethod("getEndpointInfo"), cli.GetMethod("datagram"));
 100        r.add("endpointIsSecure", cl.GetMethod("getEndpointInfo"), cli.GetMethod("secure"));
 101        r.add("endpointCompress", cl.GetMethod("getEndpointInfo"), cli.GetField("compress"));
 102
 103        cli = typeof(Ice.IPEndpointInfo);
 104        r.add("endpointHost", cl.GetMethod("getEndpointInfo"), cli.GetField("host"));
 105        r.add("endpointPort", cl.GetMethod("getEndpointInfo"), cli.GetField("port"));
 106    }
 107
 108    public static void
 109    addConnectionAttributes<T>(MetricsHelper<T>.AttributeResolver r, Type cl) where T : IceMX.Metrics
 110    {
 111        Type cli = typeof(Ice.ConnectionInfo);
 112        r.add("incoming", cl.GetMethod("getConnectionInfo"), cli.GetField("incoming"));
 113        r.add("adapterName", cl.GetMethod("getConnectionInfo"), cli.GetField("adapterName"));
 114        r.add("connectionId", cl.GetMethod("getConnectionInfo"), cli.GetField("connectionId"));
 115
 116        cli = typeof(Ice.IPConnectionInfo);
 117        r.add("localHost", cl.GetMethod("getConnectionInfo"), cli.GetField("localAddress"));
 118        r.add("localPort", cl.GetMethod("getConnectionInfo"), cli.GetField("localPort"));
 119        r.add("remoteHost", cl.GetMethod("getConnectionInfo"), cli.GetField("remoteAddress"));
 120        r.add("remotePort", cl.GetMethod("getConnectionInfo"), cli.GetField("remotePort"));
 121
 122        cli = typeof(Ice.UDPConnectionInfo);
 123        r.add("mcastHost", cl.GetMethod("getConnectionInfo"), cli.GetField("mcastAddress"));
 124        r.add("mcastPort", cl.GetMethod("getConnectionInfo"), cli.GetField("mcastPort"));
 125
 126        addEndpointAttributes<T>(r, cl);
 127    }
 128}
 129
 130internal class ConnectionHelper : MetricsHelper<ConnectionMetrics>
 131{
 132    private class AttributeResolverI : AttributeResolver
 133    {
 134        public AttributeResolverI()
 135        {
 136            try
 137            {
 138                Type cl = typeof(ConnectionHelper);
 139                add("parent", cl.GetMethod("getParent"));
 140                add("id", cl.GetMethod("getId"));
 141                add("state", cl.GetMethod("getState"));
 142                AttrsUtil.addConnectionAttributes(this, cl);
 143            }
 144            catch (System.Exception)
 145            {
 146                Debug.Assert(false);
 147            }
 148        }
 149    }
 150
 151    private static readonly AttributeResolver _attributes = new AttributeResolverI();
 152
 153    public ConnectionHelper(Ice.ConnectionInfo con, Ice.Endpoint endpt, Ice.Instrumentation.ConnectionState state)
 154        : base(_attributes)
 155    {
 156        _connectionInfo = con;
 157        _endpoint = endpt;
 158        _state = state;
 159    }
 160
 161    public string getId()
 162    {
 163        if (_id == null)
 164        {
 165            var os = new StringBuilder();
 166            Ice.IPConnectionInfo info = getIPConnectionInfo();
 167            if (info != null)
 168            {
 169                os.Append(info.localAddress).Append(':').Append(info.localPort);
 170                os.Append(" -> ");
 171                os.Append(info.remoteAddress).Append(':').Append(info.remotePort);
 172            }
 173            else
 174            {
 175                os.Append("connection-").Append(_connectionInfo);
 176            }
 177            if (_connectionInfo.connectionId.Length > 0)
 178            {
 179                os.Append(" [").Append(_connectionInfo.connectionId).Append(']');
 180            }
 181            _id = os.ToString();
 182        }
 183        return _id;
 184    }
 185
 186    public string getState()
 187    {
 188        switch (_state)
 189        {
 190            case Ice.Instrumentation.ConnectionState.ConnectionStateValidating:
 191                return "validating";
 192            case Ice.Instrumentation.ConnectionState.ConnectionStateHolding:
 193                return "holding";
 194            case Ice.Instrumentation.ConnectionState.ConnectionStateActive:
 195                return "active";
 196            case Ice.Instrumentation.ConnectionState.ConnectionStateClosing:
 197                return "closing";
 198            case Ice.Instrumentation.ConnectionState.ConnectionStateClosed:
 199                return "closed";
 200            default:
 201                Debug.Assert(false);
 202                return "";
 203        }
 204    }
 205
 206    public string getParent()
 207    {
 208        if (_connectionInfo.adapterName != null && _connectionInfo.adapterName.Length > 0)
 209        {
 210            return _connectionInfo.adapterName;
 211        }
 212        else
 213        {
 214            return "Communicator";
 215        }
 216    }
 217
 218    public Ice.ConnectionInfo getConnectionInfo() => _connectionInfo;
 219
 220    public Ice.Endpoint getEndpoint() => _endpoint;
 221
 222    public Ice.EndpointInfo getEndpointInfo()
 223    {
 224        _endpointInfo ??= _endpoint.getInfo();
 225        return _endpointInfo;
 226    }
 227
 228    private Ice.IPConnectionInfo
 229    getIPConnectionInfo()
 230    {
 231        for (Ice.ConnectionInfo p = _connectionInfo; p != null; p = p.underlying)
 232        {
 233            if (p is Ice.IPConnectionInfo)
 234            {
 235                return (Ice.IPConnectionInfo)p;
 236            }
 237        }
 238        return null;
 239    }
 240
 241    private readonly Ice.ConnectionInfo _connectionInfo;
 242    private readonly Ice.Endpoint _endpoint;
 243    private readonly Ice.Instrumentation.ConnectionState _state;
 244    private string _id;
 245    private Ice.EndpointInfo _endpointInfo;
 246}
 247
 248internal class DispatchHelper : MetricsHelper<DispatchMetrics>
 249{
 250    private class AttributeResolverI : AttributeResolver
 251    {
 252        public AttributeResolverI()
 253        {
 254            try
 255            {
 256                Type cl = typeof(DispatchHelper);
 257                add("parent", cl.GetMethod("getParent"));
 258                add("id", cl.GetMethod("getId"));
 259
 260                AttrsUtil.addConnectionAttributes(this, cl);
 261
 262                Type clc = typeof(Ice.Current);
 263                add("operation", cl.GetMethod("getCurrent"), clc.GetProperty("operation"));
 264                add("identity", cl.GetMethod("getIdentity"));
 265                add("facet", cl.GetMethod("getCurrent"), clc.GetProperty("facet"));
 266                add("requestId", cl.GetMethod("getCurrent"), clc.GetProperty("requestId"));
 267                add("mode", cl.GetMethod("getMode"));
 268            }
 269            catch (System.Exception)
 270            {
 271                Debug.Assert(false);
 272            }
 273        }
 274    }
 275
 276    private static readonly AttributeResolver _attributes = new AttributeResolverI();
 277
 278    public DispatchHelper(Ice.Current current, int size)
 279        : base(_attributes)
 280    {
 281        _current = current;
 282        _size = size;
 283    }
 284
 285    protected override string defaultResolve(string attribute)
 286    {
 287        if (attribute.IndexOf("context.", 0, StringComparison.Ordinal) == 0)
 288        {
 289            if (_current.ctx.TryGetValue(attribute[8..], out string v))
 290            {
 291                return v;
 292            }
 293        }
 294        throw new ArgumentOutOfRangeException(attribute);
 295    }
 296
 297    public override void initMetrics(DispatchMetrics v) => v.size += _size;
 298
 299    public string getMode() => _current.requestId == 0 ? "oneway" : "twoway";
 300
 301    public string getId()
 302    {
 303        if (_id == null)
 304        {
 305            var os = new StringBuilder();
 306            if (_current.id.category.Length > 0)
 307            {
 308                os.Append(_current.id.category).Append('/');
 309            }
 310            os.Append(_current.id.name).Append(" [").Append(_current.operation).Append(']');
 311            _id = os.ToString();
 312        }
 313        return _id;
 314    }
 315
 316    public string getParent() => _current.adapter.getName();
 317
 318    public Ice.ConnectionInfo getConnectionInfo()
 319    {
 320        if (_current.con != null)
 321        {
 322            return _current.con.getInfo();
 323        }
 324        return null;
 325    }
 326
 327    public Ice.Endpoint getEndpoint()
 328    {
 329        if (_current.con != null)
 330        {
 331            return _current.con.getEndpoint();
 332        }
 333        return null;
 334    }
 335
 336    public Ice.Connection getConnection() => _current.con;
 337
 338    public Ice.EndpointInfo getEndpointInfo()
 339    {
 340        if (_current.con != null && _endpointInfo == null)
 341        {
 342            _endpointInfo = _current.con.getEndpoint().getInfo();
 343        }
 344        return _endpointInfo;
 345    }
 346
 347    public Ice.Current getCurrent() => _current;
 348
 349    public string getIdentity() => _current.adapter.getCommunicator().identityToString(_current.id);
 350
 351    private readonly Ice.Current _current;
 352    private readonly int _size;
 353    private string _id;
 354    private Ice.EndpointInfo _endpointInfo;
 355}
 356
 357internal class InvocationHelper : MetricsHelper<InvocationMetrics>
 358{
 359    private class AttributeResolverI : AttributeResolver
 360    {
 361        public AttributeResolverI()
 362        {
 363            try
 364            {
 365                Type cl = typeof(InvocationHelper);
 366                add("parent", cl.GetMethod("getParent"));
 367                add("id", cl.GetMethod("getId"));
 368
 369                add("operation", cl.GetMethod("getOperation"));
 370                add("identity", cl.GetMethod("getIdentity"));
 371
 372                Type cli = typeof(Ice.ObjectPrx);
 373                add("facet", cl.GetMethod("getProxy"), cli.GetMethod("ice_getFacet"));
 374                add("encoding", cl.GetMethod("getEncodingVersion"));
 375                add("mode", cl.GetMethod("getMode"));
 376                add("proxy", cl.GetMethod("getProxy"));
 377            }
 378            catch (System.Exception)
 379            {
 380                Debug.Assert(false);
 381            }
 382        }
 383    }
 384
 385    private static readonly AttributeResolver _attributes = new AttributeResolverI();
 386
 387    public InvocationHelper(Ice.ObjectPrx proxy, string op, Dictionary<string, string> ctx)
 388        : base(_attributes)
 389    {
 390        _proxy = proxy;
 391        _operation = op;
 392        _context = ctx;
 393    }
 394
 395    protected override string defaultResolve(string attribute)
 396    {
 397        if (attribute.IndexOf("context.", 0, StringComparison.Ordinal) == 0)
 398        {
 399            if (_context.TryGetValue(attribute[8..], out string v))
 400            {
 401                return v;
 402            }
 403        }
 404        throw new ArgumentOutOfRangeException(attribute);
 405    }
 406
 407    public string getMode()
 408    {
 409        if (_proxy == null)
 410        {
 411            throw new ArgumentOutOfRangeException("mode");
 412        }
 413
 414        if (_proxy.ice_isTwoway())
 415        {
 416            return "twoway";
 417        }
 418        else if (_proxy.ice_isOneway())
 419        {
 420            return "oneway";
 421        }
 422        else if (_proxy.ice_isBatchOneway())
 423        {
 424            return "batch-oneway";
 425        }
 426        else if (_proxy.ice_isDatagram())
 427        {
 428            return "datagram";
 429        }
 430        else if (_proxy.ice_isBatchDatagram())
 431        {
 432            return "batch-datagram";
 433        }
 434        else
 435        {
 436            throw new ArgumentOutOfRangeException("mode");
 437        }
 438    }
 439
 440    public string getId()
 441    {
 442        if (_id == null)
 443        {
 444            if (_proxy != null)
 445            {
 446                var os = new StringBuilder();
 447                try
 448                {
 449                    os.Append(_proxy.ice_endpoints(emptyEndpoints)).Append(" [").Append(_operation).Append(']');
 450                }
 451                catch (Ice.Exception)
 452                {
 453                    // Either a fixed proxy or the communicator is destroyed.
 454                    os.Append(_proxy.ice_getCommunicator().identityToString(_proxy.ice_getIdentity()));
 455                    os.Append(" [").Append(_operation).Append(']');
 456                }
 457                _id = os.ToString();
 458            }
 459            else
 460            {
 461                _id = _operation;
 462            }
 463        }
 464        return _id;
 465    }
 466
 467    public string getParent() => "Communicator";
 468
 469    public Ice.ObjectPrx getProxy() => _proxy;
 470
 471    public string getEncodingVersion() => Ice.Util.encodingVersionToString(_proxy.ice_getEncodingVersion());
 472
 473    public string getIdentity()
 474    {
 475        if (_proxy != null)
 476        {
 477            return _proxy.ice_getCommunicator().identityToString(_proxy.ice_getIdentity());
 478        }
 479        else
 480        {
 481            return "";
 482        }
 483    }
 484
 485    public string getOperation() => _operation;
 486
 487    private static readonly Ice.Endpoint[] emptyEndpoints = [];
 488    private readonly Ice.ObjectPrx _proxy;
 489    private readonly string _operation;
 490    private readonly Dictionary<string, string> _context;
 491    private string _id;
 492}
 493
 494internal class ThreadHelper : MetricsHelper<ThreadMetrics>
 495{
 496    private class AttributeResolverI : AttributeResolver
 497    {
 498        public AttributeResolverI()
 499        {
 500            try
 501            {
 502                Type cl = typeof(ThreadHelper);
 503                add("parent", cl.GetField("_parent"));
 504                add("id", cl.GetField("_id"));
 505            }
 506            catch (System.Exception)
 507            {
 508                Debug.Assert(false);
 509            }
 510        }
 511    }
 512
 513    private static readonly AttributeResolver _attributes = new AttributeResolverI();
 514
 515    public ThreadHelper(string parent, string id, Ice.Instrumentation.ThreadState state)
 516        : base(_attributes)
 517    {
 518        _parent = parent;
 519        _id = id;
 520        _state = state;
 521    }
 522
 523    public override void initMetrics(ThreadMetrics v)
 524    {
 525        switch (_state)
 526        {
 527            case Ice.Instrumentation.ThreadState.ThreadStateInUseForIO:
 528                ++v.inUseForIO;
 529                break;
 530            case Ice.Instrumentation.ThreadState.ThreadStateInUseForUser:
 531                ++v.inUseForUser;
 532                break;
 533            case Ice.Instrumentation.ThreadState.ThreadStateInUseForOther:
 534                ++v.inUseForOther;
 535                break;
 536            default:
 537                break;
 538        }
 539    }
 540
 541    public readonly string _parent;
 542    public readonly string _id;
 543    private readonly Ice.Instrumentation.ThreadState _state;
 544}
 545
 546internal class EndpointHelper : MetricsHelper<Metrics>
 547{
 548    private class AttributeResolverI : AttributeResolver
 549    {
 550        public AttributeResolverI()
 551        {
 552            try
 553            {
 554                Type cl = typeof(EndpointHelper);
 555                add("parent", cl.GetMethod("getParent"));
 556                add("id", cl.GetMethod("getId"));
 557                AttrsUtil.addEndpointAttributes(this, cl);
 558            }
 559            catch (System.Exception)
 560            {
 561                Debug.Assert(false);
 562            }
 563        }
 564    }
 565
 566    private static readonly AttributeResolver _attributes = new AttributeResolverI();
 567
 568    public EndpointHelper(Ice.Endpoint endpt, string id)
 569        : base(_attributes)
 570    {
 571        _endpoint = endpt;
 572        _id = id;
 573    }
 574
 575    public EndpointHelper(Ice.Endpoint endpt)
 576        : base(_attributes) => _endpoint = endpt;
 577
 578    public Ice.EndpointInfo getEndpointInfo()
 579    {
 580        _endpointInfo ??= _endpoint.getInfo();
 581        return _endpointInfo;
 582    }
 583
 584    public string getParent() => "Communicator";
 585
 586    public string getId()
 587    {
 588        _id ??= _endpoint.ToString();
 589        return _id;
 590    }
 591
 592    public string getEndpoint() => _endpoint.ToString();
 593
 594    private readonly Ice.Endpoint _endpoint;
 595    private string _id;
 596    private Ice.EndpointInfo _endpointInfo;
 597}
 598
 599public class RemoteInvocationHelper : MetricsHelper<RemoteMetrics>
 600{
 601    private class AttributeResolverI : AttributeResolver
 602    {
 603        public AttributeResolverI()
 604        {
 605            try
 606            {
 607                Type cl = typeof(RemoteInvocationHelper);
 608                add("parent", cl.GetMethod("getParent"));
 609                add("id", cl.GetMethod("getId"));
 610                add("requestId", cl.GetMethod("getRequestId"));
 611                AttrsUtil.addConnectionAttributes(this, cl);
 612            }
 613            catch (System.Exception)
 614            {
 615                Debug.Assert(false);
 616            }
 617        }
 618    }
 619
 620    private static readonly AttributeResolver _attributes = new AttributeResolverI();
 621
 622    public RemoteInvocationHelper(Ice.ConnectionInfo con, Ice.Endpoint endpt, int requestId, int size)
 623        : base(_attributes)
 624    {
 625        _connectionInfo = con;
 626        _endpoint = endpt;
 627        _requestId = requestId;
 628        _size = size;
 629    }
 630
 631    public override void initMetrics(RemoteMetrics metrics) => metrics.size += _size;
 632
 633    public string getId()
 634    {
 635        if (_id == null)
 636        {
 637            _id = _endpoint.ToString();
 638            if (_connectionInfo.connectionId != null && _connectionInfo.connectionId.Length > 0)
 639            {
 640                _id += " [" + _connectionInfo.connectionId + "]";
 641            }
 642        }
 643        return _id;
 644    }
 645
 646    public int getRequestId() => _requestId;
 647
 648    public string getParent()
 649    {
 650        if (_connectionInfo.adapterName != null && _connectionInfo.adapterName.Length > 0)
 651        {
 652            return _connectionInfo.adapterName;
 653        }
 654        else
 655        {
 656            return "Communicator";
 657        }
 658    }
 659
 660    public Ice.ConnectionInfo getConnectionInfo() => _connectionInfo;
 661
 662    public Ice.Endpoint getEndpoint() => _endpoint;
 663
 664    public Ice.EndpointInfo getEndpointInfo()
 665    {
 666        _endpointInfo ??= _endpoint.getInfo();
 667        return _endpointInfo;
 668    }
 669
 670    private readonly Ice.ConnectionInfo _connectionInfo;
 671    private readonly Ice.Endpoint _endpoint;
 672    private readonly int _size;
 673    private readonly int _requestId;
 674    private string _id;
 675    private Ice.EndpointInfo _endpointInfo;
 676}
 677
 678public class CollocatedInvocationHelper : MetricsHelper<CollocatedMetrics>
 679{
 680    private class AttributeResolverI : AttributeResolver
 681    {
 682        public AttributeResolverI()
 683        {
 684            try
 685            {
 686                Type cl = typeof(CollocatedInvocationHelper);
 687                add("parent", cl.GetMethod("getParent"));
 688                add("id", cl.GetMethod("getId"));
 689                add("requestId", cl.GetMethod("getRequestId"));
 690            }
 691            catch (System.Exception)
 692            {
 693                Debug.Assert(false);
 694            }
 695        }
 696    }
 697
 698    private static readonly AttributeResolver _attributes = new AttributeResolverI();
 699
 700    public CollocatedInvocationHelper(Ice.ObjectAdapter adapter, int requestId, int size)
 701        : base(_attributes)
 702    {
 703        _id = adapter.getName();
 704        _requestId = requestId;
 705        _size = size;
 706    }
 707
 708    public override void initMetrics(CollocatedMetrics metrics) => metrics.size += _size;
 709
 710    public string getId() => _id;
 711
 712    public int getRequestId() => _requestId;
 713
 714    public string getParent() => "Communicator";
 715
 716    private readonly int _size;
 717    private readonly int _requestId;
 718    private readonly string _id;
 719}
 720
 721public class ObserverWithDelegateI : ObserverWithDelegate<Metrics, Ice.Instrumentation.Observer>
 722{
 723}
 724
 725public class ConnectionObserverI : ObserverWithDelegate<ConnectionMetrics, Ice.Instrumentation.ConnectionObserver>,
 726    Ice.Instrumentation.ConnectionObserver
 727{
 728    public void sentBytes(int num)
 729    {
 1730        _sentBytes = num;
 1731        forEach(sentBytesUpdate);
 1732        delegate_?.sentBytes(num);
 1733    }
 734
 735    public void receivedBytes(int num)
 736    {
 1737        _receivedBytes = num;
 1738        forEach(receivedBytesUpdate);
 1739        delegate_?.receivedBytes(num);
 1740    }
 741
 1742    private void sentBytesUpdate(ConnectionMetrics v) => v.sentBytes += _sentBytes;
 743
 1744    private void receivedBytesUpdate(ConnectionMetrics v) => v.receivedBytes += _receivedBytes;
 745
 746    private int _sentBytes;
 747    private int _receivedBytes;
 748}
 749
 750public class DispatchObserverI : ObserverWithDelegate<DispatchMetrics, Ice.Instrumentation.DispatchObserver>,
 751    Ice.Instrumentation.DispatchObserver
 752{
 753    public void
 754    userException()
 755    {
 756        forEach(userException);
 757        delegate_?.userException();
 758    }
 759
 760    public void reply(int size)
 761    {
 762        forEach((DispatchMetrics v) => v.replySize += size);
 763        delegate_?.reply(size);
 764    }
 765
 766    private void userException(DispatchMetrics v) => ++v.userException;
 767}
 768
 769public class RemoteObserverI : ObserverWithDelegate<RemoteMetrics, Ice.Instrumentation.RemoteObserver>,
 770    Ice.Instrumentation.RemoteObserver
 771{
 772    public void reply(int size)
 773    {
 774        forEach((RemoteMetrics v) => v.replySize += size);
 775        delegate_?.reply(size);
 776    }
 777}
 778
 779public class CollocatedObserverI : ObserverWithDelegate<CollocatedMetrics, Ice.Instrumentation.CollocatedObserver>,
 780    Ice.Instrumentation.CollocatedObserver
 781{
 782    public void reply(int size)
 783    {
 784        forEach((CollocatedMetrics v) => v.replySize += size);
 785        delegate_?.reply(size);
 786    }
 787}
 788
 789public class InvocationObserverI : ObserverWithDelegate<InvocationMetrics, Ice.Instrumentation.InvocationObserver>,
 790    Ice.Instrumentation.InvocationObserver
 791{
 792    public void
 793    userException()
 794    {
 795        forEach(userException);
 796        delegate_?.userException();
 797    }
 798
 799    public void
 800    retried()
 801    {
 802        forEach(incrementRetry);
 803        delegate_?.retried();
 804    }
 805
 806    public Ice.Instrumentation.RemoteObserver getRemoteObserver(
 807        Ice.ConnectionInfo con,
 808        Ice.Endpoint endpt,
 809        int requestId,
 810        int size)
 811    {
 812        Ice.Instrumentation.RemoteObserver del = null;
 813        if (delegate_ != null)
 814        {
 815            del = delegate_.getRemoteObserver(con, endpt, requestId, size);
 816        }
 817        return getObserver<RemoteMetrics, RemoteObserverI,
 818            Ice.Instrumentation.RemoteObserver>(
 819                "Remote",
 820                new RemoteInvocationHelper(con, endpt, requestId, size),
 821                del);
 822    }
 823
 824    public Ice.Instrumentation.CollocatedObserver getCollocatedObserver(
 825        Ice.ObjectAdapter adapter,
 826        int requestId,
 827        int size)
 828    {
 829        Ice.Instrumentation.CollocatedObserver del = null;
 830        if (delegate_ != null)
 831        {
 832            del = delegate_.getCollocatedObserver(adapter, requestId, size);
 833        }
 834        return getObserver<CollocatedMetrics, CollocatedObserverI,
 835            Ice.Instrumentation.CollocatedObserver>(
 836                "Collocated",
 837                new CollocatedInvocationHelper(adapter, requestId, size),
 838                del);
 839    }
 840
 841    private void incrementRetry(InvocationMetrics v) => ++v.retry;
 842
 843    private void userException(InvocationMetrics v) => ++v.userException;
 844}
 845
 846public class ThreadObserverI : ObserverWithDelegate<ThreadMetrics, Ice.Instrumentation.ThreadObserver>,
 847    Ice.Instrumentation.ThreadObserver
 848{
 849    public void stateChanged(Ice.Instrumentation.ThreadState oldState, Ice.Instrumentation.ThreadState newState)
 850    {
 851        _oldState = oldState;
 852        _newState = newState;
 853        forEach(threadStateUpdate);
 854        delegate_?.stateChanged(oldState, newState);
 855    }
 856
 857    private void threadStateUpdate(ThreadMetrics v)
 858    {
 859        switch (_oldState)
 860        {
 861            case Ice.Instrumentation.ThreadState.ThreadStateInUseForIO:
 862                --v.inUseForIO;
 863                break;
 864            case Ice.Instrumentation.ThreadState.ThreadStateInUseForUser:
 865                --v.inUseForUser;
 866                break;
 867            case Ice.Instrumentation.ThreadState.ThreadStateInUseForOther:
 868                --v.inUseForOther;
 869                break;
 870            default:
 871                break;
 872        }
 873        switch (_newState)
 874        {
 875            case Ice.Instrumentation.ThreadState.ThreadStateInUseForIO:
 876                ++v.inUseForIO;
 877                break;
 878            case Ice.Instrumentation.ThreadState.ThreadStateInUseForUser:
 879                ++v.inUseForUser;
 880                break;
 881            case Ice.Instrumentation.ThreadState.ThreadStateInUseForOther:
 882                ++v.inUseForOther;
 883                break;
 884            default:
 885                break;
 886        }
 887    }
 888
 889    private Ice.Instrumentation.ThreadState _oldState;
 890    private Ice.Instrumentation.ThreadState _newState;
 891}
 892
 893public class CommunicatorObserverI : Ice.Instrumentation.CommunicatorObserver
 894{
 895    public CommunicatorObserverI(Ice.InitializationData initData)
 896    {
 897        _metrics = new MetricsAdminI(initData.properties, initData.logger);
 898        _delegate = initData.observer;
 899        _connections = new ObserverFactoryWithDelegate<ConnectionMetrics, ConnectionObserverI,
 900            Ice.Instrumentation.ConnectionObserver>(_metrics, "Connection");
 901        _dispatch = new ObserverFactoryWithDelegate<DispatchMetrics, DispatchObserverI,
 902            Ice.Instrumentation.DispatchObserver>(_metrics, "Dispatch");
 903        _invocations = new ObserverFactoryWithDelegate<InvocationMetrics, InvocationObserverI,
 904            Ice.Instrumentation.InvocationObserver>(_metrics, "Invocation");
 905        _threads = new ObserverFactoryWithDelegate<ThreadMetrics, ThreadObserverI,
 906            Ice.Instrumentation.ThreadObserver>(_metrics, "Thread");
 907        _connects = new ObserverFactoryWithDelegate<Metrics, ObserverWithDelegateI,
 908            Ice.Instrumentation.Observer>(_metrics, "ConnectionEstablishment");
 909        _endpointLookups = new ObserverFactoryWithDelegate<Metrics, ObserverWithDelegateI,
 910            Ice.Instrumentation.Observer>(_metrics, "EndpointLookup");
 911
 912        try
 913        {
 914            Type cl = typeof(InvocationMetrics);
 915            _invocations.registerSubMap<RemoteMetrics>("Remote", cl.GetField("remotes"));
 916            _invocations.registerSubMap<CollocatedMetrics>("Collocated", cl.GetField("collocated"));
 917        }
 918        catch (System.Exception)
 919        {
 920            Debug.Assert(false);
 921        }
 922    }
 923
 924    public Ice.Instrumentation.Observer getConnectionEstablishmentObserver(Ice.Endpoint endpt, string connector)
 925    {
 926        if (_connects.isEnabled())
 927        {
 928            try
 929            {
 930                Ice.Instrumentation.Observer del = null;
 931                if (_delegate != null)
 932                {
 933                    del = _delegate.getConnectionEstablishmentObserver(endpt, connector);
 934                }
 935                return _connects.getObserver(new EndpointHelper(endpt, connector), del);
 936            }
 937            catch (System.Exception ex)
 938            {
 939                _metrics.getLogger().error("unexpected exception trying to obtain observer:\n" + ex);
 940            }
 941        }
 942        return null;
 943    }
 944
 945    public Ice.Instrumentation.Observer getEndpointLookupObserver(Ice.Endpoint endpt)
 946    {
 947        if (_endpointLookups.isEnabled())
 948        {
 949            try
 950            {
 951                Ice.Instrumentation.Observer del = null;
 952                if (_delegate != null)
 953                {
 954                    del = _delegate.getEndpointLookupObserver(endpt);
 955                }
 956                return _endpointLookups.getObserver(new EndpointHelper(endpt), del);
 957            }
 958            catch (System.Exception ex)
 959            {
 960                _metrics.getLogger().error("unexpected exception trying to obtain observer:\n" + ex);
 961            }
 962        }
 963        return null;
 964    }
 965
 966    public Ice.Instrumentation.ConnectionObserver getConnectionObserver(
 967        Ice.ConnectionInfo c,
 968        Ice.Endpoint e,
 969        Ice.Instrumentation.ConnectionState s,
 970        Ice.Instrumentation.ConnectionObserver o)
 971    {
 972        if (_connections.isEnabled())
 973        {
 974            try
 975            {
 976                Ice.Instrumentation.ConnectionObserver del = null;
 977                ConnectionObserverI obsv = o is ConnectionObserverI ? (ConnectionObserverI)o : null;
 978                if (_delegate != null)
 979                {
 980                    del = _delegate.getConnectionObserver(c, e, s, obsv is not null ? obsv.getDelegate() : o);
 981                }
 982                return _connections.getObserver(new ConnectionHelper(c, e, s), o, del);
 983            }
 984            catch (System.Exception ex)
 985            {
 986                _metrics.getLogger().error("unexpected exception trying to obtain observer:\n" + ex);
 987            }
 988        }
 989        return null;
 990    }
 991
 992    public Ice.Instrumentation.ThreadObserver getThreadObserver(
 993        string parent,
 994        string id,
 995        Ice.Instrumentation.ThreadState s,
 996        Ice.Instrumentation.ThreadObserver o)
 997    {
 998        if (_threads.isEnabled())
 999        {
 1000            try
 1001            {
 1002                Ice.Instrumentation.ThreadObserver del = null;
 1003                ThreadObserverI obsv = o is ThreadObserverI ? (ThreadObserverI)o : null;
 1004                if (_delegate != null)
 1005                {
 1006                    del = _delegate.getThreadObserver(parent, id, s, obsv is not null ? obsv.getDelegate() : o);
 1007                }
 1008                return _threads.getObserver(new ThreadHelper(parent, id, s), o, del);
 1009            }
 1010            catch (System.Exception ex)
 1011            {
 1012                _metrics.getLogger().error("unexpected exception trying to obtain observer:\n" + ex);
 1013            }
 1014        }
 1015        return null;
 1016    }
 1017
 1018    public Ice.Instrumentation.InvocationObserver getInvocationObserver(
 1019        Ice.ObjectPrx prx,
 1020        string operation,
 1021        Dictionary<string, string> ctx)
 1022    {
 1023        if (_invocations.isEnabled())
 1024        {
 1025            try
 1026            {
 1027                Ice.Instrumentation.InvocationObserver del = null;
 1028                if (_delegate != null)
 1029                {
 1030                    del = _delegate.getInvocationObserver(prx, operation, ctx);
 1031                }
 1032                return _invocations.getObserver(new InvocationHelper(prx, operation, ctx), del);
 1033            }
 1034            catch (System.Exception ex)
 1035            {
 1036                _metrics.getLogger().error("unexpected exception trying to obtain observer:\n" + ex);
 1037            }
 1038        }
 1039        return null;
 1040    }
 1041
 1042    public Ice.Instrumentation.DispatchObserver getDispatchObserver(Ice.Current c, int size)
 1043    {
 1044        if (_dispatch.isEnabled())
 1045        {
 1046            try
 1047            {
 1048                Ice.Instrumentation.DispatchObserver del = null;
 1049                if (_delegate != null)
 1050                {
 1051                    del = _delegate.getDispatchObserver(c, size);
 1052                }
 1053                return _dispatch.getObserver(new DispatchHelper(c, size), del);
 1054            }
 1055            catch (System.Exception ex)
 1056            {
 1057                _metrics.getLogger().error("unexpected exception trying to obtain observer:\n" + ex);
 1058            }
 1059        }
 1060        return null;
 1061    }
 1062
 1063    public void setObserverUpdater(Ice.Instrumentation.ObserverUpdater updater)
 1064    {
 1065        if (updater == null)
 1066        {
 1067            _connections.setUpdater(null);
 1068            _threads.setUpdater(null);
 1069        }
 1070        else
 1071        {
 1072            _connections.setUpdater(updater.updateConnectionObservers);
 1073            _threads.setUpdater(updater.updateThreadObservers);
 1074        }
 1075        _delegate?.setObserverUpdater(updater);
 1076    }
 1077
 1078    public MetricsAdminI getFacet() => _metrics;
 1079
 1080    private readonly MetricsAdminI _metrics;
 1081    private readonly Ice.Instrumentation.CommunicatorObserver _delegate;
 1082
 1083    private readonly ObserverFactoryWithDelegate<ConnectionMetrics, ConnectionObserverI,
 1084        Ice.Instrumentation.ConnectionObserver> _connections;
 1085
 1086    private readonly ObserverFactoryWithDelegate<DispatchMetrics, DispatchObserverI,
 1087        Ice.Instrumentation.DispatchObserver> _dispatch;
 1088
 1089    private readonly ObserverFactoryWithDelegate<InvocationMetrics, InvocationObserverI,
 1090        Ice.Instrumentation.InvocationObserver> _invocations;
 1091
 1092    private readonly ObserverFactoryWithDelegate<ThreadMetrics, ThreadObserverI,
 1093        Ice.Instrumentation.ThreadObserver> _threads;
 1094
 1095    private readonly ObserverFactoryWithDelegate<Metrics, ObserverWithDelegateI,
 1096        Ice.Instrumentation.Observer> _connects;
 1097
 1098    private readonly ObserverFactoryWithDelegate<Metrics, ObserverWithDelegateI,
 1099        Ice.Instrumentation.Observer> _endpointLookups;
 1100}