// // Copyright (c) ZeroC, Inc. All rights reserved. // namespace IceInternal { using System; using System.Diagnostics; using System.Text; using System.Collections.Generic; using IceMX; public class ObserverWithDelegate : Observer where T : Metrics, new() where O : Ice.Instrumentation.Observer { override public void attach() { base.attach(); if(delegate_ != null) { delegate_.attach(); } } override public void detach() { base.detach(); if(delegate_ != null) { delegate_.detach(); } } override public void failed(string exceptionName) { base.failed(exceptionName); if(delegate_ != null) { delegate_.failed(exceptionName); } } public O getDelegate() { return delegate_; } public void setDelegate(O del) { delegate_ = del; } public Observer getObserver(string mapName, MetricsHelper helper, Observer del) where S : Metrics, new() where ObserverImpl : ObserverWithDelegate, Observer, new() where Observer : Ice.Instrumentation.Observer { ObserverImpl obsv = getObserver(mapName, helper); if(obsv != null) { obsv.setDelegate(del); return obsv; } return del; } protected O delegate_; } public class ObserverFactoryWithDelegate : ObserverFactory where T : Metrics, new() where OImpl : ObserverWithDelegate, O, new() where O : Ice.Instrumentation.Observer { public ObserverFactoryWithDelegate(MetricsAdminI metrics, string name) : base(metrics, name) { } public O getObserver(MetricsHelper helper, O del) { OImpl o = getObserver(helper); if(o != null) { o.setDelegate(del); return o; } return del; } public O getObserver(MetricsHelper helper, object observer, O del) { OImpl o = getObserver(helper, observer); if(o != null) { o.setDelegate(del); return o; } return del; } } static class AttrsUtil { public static void addEndpointAttributes(MetricsHelper.AttributeResolver r, Type cl) where T : IceMX.Metrics { r.add("endpoint", cl.GetMethod("getEndpoint")); Type cli = typeof(Ice.EndpointInfo); r.add("endpointType", cl.GetMethod("getEndpointInfo"), cli.GetMethod("type")); r.add("endpointIsDatagram", cl.GetMethod("getEndpointInfo"), cli.GetMethod("datagram")); r.add("endpointIsSecure", cl.GetMethod("getEndpointInfo"), cli.GetMethod("secure")); r.add("endpointTimeout", cl.GetMethod("getEndpointInfo"), cli.GetField("timeout")); r.add("endpointCompress", cl.GetMethod("getEndpointInfo"), cli.GetField("compress")); cli = typeof(Ice.IPEndpointInfo); r.add("endpointHost", cl.GetMethod("getEndpointInfo"), cli.GetField("host")); r.add("endpointPort", cl.GetMethod("getEndpointInfo"), cli.GetField("port")); } public static void addConnectionAttributes(MetricsHelper.AttributeResolver r, Type cl) where T : IceMX.Metrics { Type cli = typeof(Ice.ConnectionInfo); r.add("incoming", cl.GetMethod("getConnectionInfo"), cli.GetField("incoming")); r.add("adapterName", cl.GetMethod("getConnectionInfo"), cli.GetField("adapterName")); r.add("connectionId", cl.GetMethod("getConnectionInfo"), cli.GetField("connectionId")); cli = typeof(Ice.IPConnectionInfo); r.add("localHost", cl.GetMethod("getConnectionInfo"), cli.GetField("localAddress")); r.add("localPort", cl.GetMethod("getConnectionInfo"), cli.GetField("localPort")); r.add("remoteHost", cl.GetMethod("getConnectionInfo"), cli.GetField("remoteAddress")); r.add("remotePort", cl.GetMethod("getConnectionInfo"), cli.GetField("remotePort")); cli = typeof(Ice.UDPConnectionInfo); r.add("mcastHost", cl.GetMethod("getConnectionInfo"), cli.GetField("mcastAddress")); r.add("mcastPort", cl.GetMethod("getConnectionInfo"), cli.GetField("mcastPort")); addEndpointAttributes(r, cl); } } class ConnectionHelper : MetricsHelper { class AttributeResolverI : AttributeResolver { public AttributeResolverI() { try { Type cl = typeof(ConnectionHelper); add("parent", cl.GetMethod("getParent")); add("id", cl.GetMethod("getId")); add("state", cl.GetMethod("getState")); AttrsUtil.addConnectionAttributes(this, cl); } catch(Exception) { Debug.Assert(false); } } } static AttributeResolver _attributes = new AttributeResolverI(); public ConnectionHelper(Ice.ConnectionInfo con, Ice.Endpoint endpt, Ice.Instrumentation.ConnectionState state) : base(_attributes) { _connectionInfo = con; _endpoint = endpt; _state = state; } public string getId() { if(_id == null) { StringBuilder os = new StringBuilder(); Ice.IPConnectionInfo info = getIPConnectionInfo(); if(info != null) { os.Append(info.localAddress).Append(':').Append(info.localPort); os.Append(" -> "); os.Append(info.remoteAddress).Append(':').Append(info.remotePort); } else { os.Append("connection-").Append(_connectionInfo); } if(_connectionInfo.connectionId.Length > 0) { os.Append(" [").Append(_connectionInfo.connectionId).Append("]"); } _id = os.ToString(); } return _id; } public string getState() { switch(_state) { case Ice.Instrumentation.ConnectionState.ConnectionStateValidating: return "validating"; case Ice.Instrumentation.ConnectionState.ConnectionStateHolding: return "holding"; case Ice.Instrumentation.ConnectionState.ConnectionStateActive: return "active"; case Ice.Instrumentation.ConnectionState.ConnectionStateClosing: return "closing"; case Ice.Instrumentation.ConnectionState.ConnectionStateClosed: return "closed"; default: Debug.Assert(false); return ""; } } public string getParent() { if(_connectionInfo.adapterName != null && _connectionInfo.adapterName.Length > 0) { return _connectionInfo.adapterName; } else { return "Communicator"; } } public Ice.ConnectionInfo getConnectionInfo() { return _connectionInfo; } public Ice.Endpoint getEndpoint() { return _endpoint; } public Ice.EndpointInfo getEndpointInfo() { if(_endpointInfo == null) { _endpointInfo = _endpoint.getInfo(); } return _endpointInfo; } private Ice.IPConnectionInfo getIPConnectionInfo() { for(Ice.ConnectionInfo p = _connectionInfo; p != null; p = p.underlying) { if(p is Ice.IPConnectionInfo) { return (Ice.IPConnectionInfo)p; } } return null; } readonly private Ice.ConnectionInfo _connectionInfo; readonly private Ice.Endpoint _endpoint; readonly private Ice.Instrumentation.ConnectionState _state; private string _id; private Ice.EndpointInfo _endpointInfo; } class DispatchHelper : MetricsHelper { class AttributeResolverI : AttributeResolver { public AttributeResolverI() { try { Type cl = typeof(DispatchHelper); add("parent", cl.GetMethod("getParent")); add("id", cl.GetMethod("getId")); AttrsUtil.addConnectionAttributes(this, cl); Type clc = typeof(Ice.Current); add("operation", cl.GetMethod("getCurrent"), clc.GetField("operation")); add("identity", cl.GetMethod("getIdentity")); add("facet", cl.GetMethod("getCurrent"), clc.GetField("facet")); add("requestId", cl.GetMethod("getCurrent"), clc.GetField("requestId")); add("mode", cl.GetMethod("getMode")); } catch(Exception) { Debug.Assert(false); } } } static AttributeResolver _attributes = new AttributeResolverI(); public DispatchHelper(Ice.Current current, int size) : base(_attributes) { _current = current; _size = size; } override protected string defaultResolve(string attribute) { if(attribute.IndexOf("context.", 0) == 0) { string v; if(_current.ctx.TryGetValue(attribute.Substring(8), out v)) { return v; } } throw new ArgumentOutOfRangeException(attribute); } override public void initMetrics(DispatchMetrics v) { v.size += _size; } public string getMode() { return _current.requestId == 0 ? "oneway" : "twoway"; } public string getId() { if(_id == null) { StringBuilder os = new StringBuilder(); if(_current.id.category != null && _current.id.category.Length > 0) { os.Append(_current.id.category).Append('/'); } os.Append(_current.id.name).Append(" [").Append(_current.operation).Append(']'); _id = os.ToString(); } return _id; } public string getParent() { return _current.adapter.getName(); } public Ice.ConnectionInfo getConnectionInfo() { if(_current.con != null) { return _current.con.getInfo(); } return null; } public Ice.Endpoint getEndpoint() { if(_current.con != null) { return _current.con.getEndpoint(); } return null; } public Ice.Connection getConnection() { return _current.con; } public Ice.EndpointInfo getEndpointInfo() { if(_current.con != null && _endpointInfo == null) { _endpointInfo = _current.con.getEndpoint().getInfo(); } return _endpointInfo; } public Ice.Current getCurrent() { return _current; } public string getIdentity() { return _current.adapter.getCommunicator().identityToString(_current.id); } readonly private Ice.Current _current; readonly private int _size; private string _id; private Ice.EndpointInfo _endpointInfo; } class InvocationHelper : MetricsHelper { class AttributeResolverI : AttributeResolver { public AttributeResolverI() { try { Type cl = typeof(InvocationHelper); add("parent", cl.GetMethod("getParent")); add("id", cl.GetMethod("getId")); add("operation", cl.GetMethod("getOperation")); add("identity", cl.GetMethod("getIdentity")); Type cli = typeof(Ice.ObjectPrx); add("facet", cl.GetMethod("getProxy"), cli.GetMethod("ice_getFacet")); add("encoding", cl.GetMethod("getEncodingVersion")); add("mode", cl.GetMethod("getMode")); add("proxy", cl.GetMethod("getProxy")); } catch(Exception) { Debug.Assert(false); } } } static AttributeResolver _attributes = new AttributeResolverI(); public InvocationHelper(Ice.ObjectPrx proxy, string op, Dictionary ctx) : base(_attributes) { _proxy = proxy; _operation = op; _context = ctx; } override protected string defaultResolve(string attribute) { if(attribute.IndexOf("context.", 0) == 0) { string v; if(_context.TryGetValue(attribute.Substring(8), out v)) { return v; } } throw new ArgumentOutOfRangeException(attribute); } public string getMode() { if(_proxy == null) { throw new ArgumentOutOfRangeException("mode"); } if(_proxy.ice_isTwoway()) { return "twoway"; } else if(_proxy.ice_isOneway()) { return "oneway"; } else if(_proxy.ice_isBatchOneway()) { return "batch-oneway"; } else if(_proxy.ice_isDatagram()) { return "datagram"; } else if(_proxy.ice_isBatchDatagram()) { return "batch-datagram"; } else { throw new ArgumentOutOfRangeException("mode"); } } public string getId() { if(_id == null) { if(_proxy != null) { StringBuilder os = new StringBuilder(); try { os.Append(_proxy.ice_endpoints(emptyEndpoints)).Append(" [").Append(_operation).Append(']'); } catch(Ice.Exception) { // Either a fixed proxy or the communicator is destroyed. os.Append(_proxy.ice_getCommunicator().identityToString(_proxy.ice_getIdentity())); os.Append(" [").Append(_operation).Append(']'); } _id = os.ToString(); } else { _id = _operation; } } return _id; } public string getParent() { return "Communicator"; } public Ice.ObjectPrx getProxy() { return _proxy; } public string getEncodingVersion() { return Ice.Util.encodingVersionToString(_proxy.ice_getEncodingVersion()); } public string getIdentity() { if(_proxy != null) { return _proxy.ice_getCommunicator().identityToString(_proxy.ice_getIdentity()); } else { return ""; } } public string getOperation() { return _operation; } readonly private Ice.ObjectPrx _proxy; readonly private string _operation; readonly private Dictionary _context; private string _id; readonly static private Ice.Endpoint[] emptyEndpoints = new Ice.Endpoint[0]; } class ThreadHelper : MetricsHelper { class AttributeResolverI : AttributeResolver { public AttributeResolverI() { try { Type cl = typeof(ThreadHelper); add("parent", cl.GetField("_parent")); add("id", cl.GetField("_id")); } catch(Exception) { Debug.Assert(false); } } } static AttributeResolver _attributes = new AttributeResolverI(); public ThreadHelper(string parent, string id, Ice.Instrumentation.ThreadState state) : base(_attributes) { _parent = parent; _id = id; _state = state; } override public void initMetrics(ThreadMetrics v) { switch(_state) { case Ice.Instrumentation.ThreadState.ThreadStateInUseForIO: ++v.inUseForIO; break; case Ice.Instrumentation.ThreadState.ThreadStateInUseForUser: ++v.inUseForUser; break; case Ice.Instrumentation.ThreadState.ThreadStateInUseForOther: ++v.inUseForOther; break; default: break; } } readonly public string _parent; readonly public string _id; readonly private Ice.Instrumentation.ThreadState _state; } class EndpointHelper : MetricsHelper { class AttributeResolverI : AttributeResolver { public AttributeResolverI() { try { Type cl = typeof(EndpointHelper); add("parent", cl.GetMethod("getParent")); add("id", cl.GetMethod("getId")); AttrsUtil.addEndpointAttributes(this, cl); } catch(Exception) { Debug.Assert(false); } } } static AttributeResolver _attributes = new AttributeResolverI(); public EndpointHelper(Ice.Endpoint endpt, string id) : base(_attributes) { _endpoint = endpt; _id = id; } public EndpointHelper(Ice.Endpoint endpt) : base(_attributes) { _endpoint = endpt; } public Ice.EndpointInfo getEndpointInfo() { if(_endpointInfo == null) { _endpointInfo = _endpoint.getInfo(); } return _endpointInfo; } public string getParent() { return "Communicator"; } public string getId() { if(_id == null) { _id = _endpoint.ToString(); } return _id; } public string getEndpoint() { return _endpoint.ToString(); } readonly private Ice.Endpoint _endpoint; private string _id; private Ice.EndpointInfo _endpointInfo; } public class RemoteInvocationHelper : MetricsHelper { class AttributeResolverI : AttributeResolver { public AttributeResolverI() { try { Type cl = typeof(RemoteInvocationHelper); add("parent", cl.GetMethod("getParent")); add("id", cl.GetMethod("getId")); add("requestId", cl.GetMethod("getRequestId")); AttrsUtil.addConnectionAttributes(this, cl); } catch(Exception) { Debug.Assert(false); } } } static AttributeResolver _attributes = new AttributeResolverI(); public RemoteInvocationHelper(Ice.ConnectionInfo con, Ice.Endpoint endpt, int requestId, int size) : base(_attributes) { _connectionInfo = con; _endpoint = endpt; _requestId = requestId; _size = size; } override public void initMetrics(RemoteMetrics v) { v.size += _size; } public string getId() { if(_id == null) { _id = _endpoint.ToString(); if(_connectionInfo.connectionId != null && _connectionInfo.connectionId.Length > 0) { _id += " [" + _connectionInfo.connectionId + "]"; } } return _id; } public int getRequestId() { return _requestId; } public string getParent() { if(_connectionInfo.adapterName != null && _connectionInfo.adapterName.Length > 0) { return _connectionInfo.adapterName; } else { return "Communicator"; } } public Ice.ConnectionInfo getConnectionInfo() { return _connectionInfo; } public Ice.Endpoint getEndpoint() { return _endpoint; } public Ice.EndpointInfo getEndpointInfo() { if(_endpointInfo == null) { _endpointInfo = _endpoint.getInfo(); } return _endpointInfo; } readonly private Ice.ConnectionInfo _connectionInfo; readonly private Ice.Endpoint _endpoint; readonly private int _size; readonly private int _requestId; private string _id; private Ice.EndpointInfo _endpointInfo; } public class CollocatedInvocationHelper : MetricsHelper { class AttributeResolverI : AttributeResolver { public AttributeResolverI() { try { Type cl = typeof(CollocatedInvocationHelper); add("parent", cl.GetMethod("getParent")); add("id", cl.GetMethod("getId")); add("requestId", cl.GetMethod("getRequestId")); } catch(Exception) { Debug.Assert(false); } } } static AttributeResolver _attributes = new AttributeResolverI(); public CollocatedInvocationHelper(Ice.ObjectAdapter adapter, int requestId, int size) : base(_attributes) { _id = adapter.getName(); _requestId = requestId; _size = size; } override public void initMetrics(CollocatedMetrics v) { v.size += _size; } public string getId() { return _id; } public int getRequestId() { return _requestId; } public string getParent() { return "Communicator"; } readonly private int _size; readonly private int _requestId; readonly private string _id; } public class ObserverWithDelegateI : ObserverWithDelegate { } public class ConnectionObserverI : ObserverWithDelegate, Ice.Instrumentation.ConnectionObserver { public void sentBytes(int num) { _sentBytes = num; forEach(sentBytesUpdate); if(delegate_ != null) { delegate_.sentBytes(num); } } public void receivedBytes(int num) { _receivedBytes = num; forEach(receivedBytesUpdate); if(delegate_ != null) { delegate_.receivedBytes(num); } } private void sentBytesUpdate(ConnectionMetrics v) { v.sentBytes += _sentBytes; } private void receivedBytesUpdate(ConnectionMetrics v) { v.receivedBytes += _receivedBytes; } private int _sentBytes; private int _receivedBytes; } public class DispatchObserverI : ObserverWithDelegate, Ice.Instrumentation.DispatchObserver { public void userException() { forEach(userException); if(delegate_ != null) { delegate_.userException(); } } public void reply(int size) { forEach((DispatchMetrics v) => { v.replySize += size; }); if(delegate_ != null) { delegate_.reply(size); } } private void userException(DispatchMetrics v) { ++v.userException; } } public class RemoteObserverI : ObserverWithDelegate, Ice.Instrumentation.RemoteObserver { public void reply(int size) { forEach((RemoteMetrics v) => { v.replySize += size; }); if(delegate_ != null) { delegate_.reply(size); } } } public class CollocatedObserverI : ObserverWithDelegate, Ice.Instrumentation.CollocatedObserver { public void reply(int size) { forEach((CollocatedMetrics v) => { v.replySize += size; }); if(delegate_ != null) { delegate_.reply(size); } } } public class InvocationObserverI : ObserverWithDelegate, Ice.Instrumentation.InvocationObserver { public void userException() { forEach(userException); if(delegate_ != null) { delegate_.userException(); } } public void retried() { forEach(incrementRetry); if(delegate_ != null) { delegate_.retried(); } } public Ice.Instrumentation.RemoteObserver getRemoteObserver(Ice.ConnectionInfo con, Ice.Endpoint endpt, int requestId, int size) { Ice.Instrumentation.RemoteObserver del = null; if(delegate_ != null) { del = delegate_.getRemoteObserver(con, endpt, requestId, size); } return getObserver("Remote", new RemoteInvocationHelper(con, endpt, requestId, size), del); } public Ice.Instrumentation.CollocatedObserver getCollocatedObserver(Ice.ObjectAdapter adapter, int requestId, int size) { Ice.Instrumentation.CollocatedObserver del = null; if(delegate_ != null) { del = delegate_.getCollocatedObserver(adapter, requestId, size); } return getObserver("Collocated", new CollocatedInvocationHelper(adapter, requestId, size), del); } private void incrementRetry(InvocationMetrics v) { ++v.retry; } private void userException(InvocationMetrics v) { ++v.userException; } } public class ThreadObserverI : ObserverWithDelegate, Ice.Instrumentation.ThreadObserver { public void stateChanged(Ice.Instrumentation.ThreadState oldState, Ice.Instrumentation.ThreadState newState) { _oldState = oldState; _newState = newState; forEach(threadStateUpdate); if(delegate_ != null) { delegate_.stateChanged(oldState, newState); } } private void threadStateUpdate(ThreadMetrics v) { switch(_oldState) { case Ice.Instrumentation.ThreadState.ThreadStateInUseForIO: --v.inUseForIO; break; case Ice.Instrumentation.ThreadState.ThreadStateInUseForUser: --v.inUseForUser; break; case Ice.Instrumentation.ThreadState.ThreadStateInUseForOther: --v.inUseForOther; break; default: break; } switch(_newState) { case Ice.Instrumentation.ThreadState.ThreadStateInUseForIO: ++v.inUseForIO; break; case Ice.Instrumentation.ThreadState.ThreadStateInUseForUser: ++v.inUseForUser; break; case Ice.Instrumentation.ThreadState.ThreadStateInUseForOther: ++v.inUseForOther; break; default: break; } } private Ice.Instrumentation.ThreadState _oldState; private Ice.Instrumentation.ThreadState _newState; } public class CommunicatorObserverI : Ice.Instrumentation.CommunicatorObserver { public CommunicatorObserverI(Ice.InitializationData initData) { _metrics = new MetricsAdminI(initData.properties, initData.logger); _delegate = initData.observer; _connections = new ObserverFactoryWithDelegate(_metrics, "Connection"); _dispatch = new ObserverFactoryWithDelegate(_metrics, "Dispatch"); _invocations = new ObserverFactoryWithDelegate(_metrics, "Invocation"); _threads = new ObserverFactoryWithDelegate(_metrics, "Thread"); _connects = new ObserverFactoryWithDelegate(_metrics, "ConnectionEstablishment"); _endpointLookups = new ObserverFactoryWithDelegate(_metrics, "EndpointLookup"); try { Type cl = typeof(InvocationMetrics); _invocations.registerSubMap("Remote", cl.GetField("remotes")); _invocations.registerSubMap("Collocated", cl.GetField("collocated")); } catch(Exception) { Debug.Assert(false); } } public Ice.Instrumentation.Observer getConnectionEstablishmentObserver(Ice.Endpoint endpt, string connector) { if(_connects.isEnabled()) { try { Ice.Instrumentation.Observer del = null; if(_delegate != null) { del = _delegate.getConnectionEstablishmentObserver(endpt, connector); } return _connects.getObserver(new EndpointHelper(endpt, connector), del); } catch(Exception ex) { _metrics.getLogger().error("unexpected exception trying to obtain observer:\n" + ex); } } return null; } public Ice.Instrumentation.Observer getEndpointLookupObserver(Ice.Endpoint endpt) { if(_endpointLookups.isEnabled()) { try { Ice.Instrumentation.Observer del = null; if(_delegate != null) { del = _delegate.getEndpointLookupObserver(endpt); } return _endpointLookups.getObserver(new EndpointHelper(endpt), del); } catch(Exception ex) { _metrics.getLogger().error("unexpected exception trying to obtain observer:\n" + ex); } } return null; } public Ice.Instrumentation.ConnectionObserver getConnectionObserver(Ice.ConnectionInfo c, Ice.Endpoint e, Ice.Instrumentation.ConnectionState s, Ice.Instrumentation.ConnectionObserver obsv) { if(_connections.isEnabled()) { try { Ice.Instrumentation.ConnectionObserver del = null; ConnectionObserverI o = obsv is ConnectionObserverI ? (ConnectionObserverI)obsv : null; if(_delegate != null) { del = _delegate.getConnectionObserver(c, e, s, o != null ? o.getDelegate() : obsv); } return _connections.getObserver(new ConnectionHelper(c, e, s), obsv, del); } catch(Exception ex) { _metrics.getLogger().error("unexpected exception trying to obtain observer:\n" + ex); } } return null; } public Ice.Instrumentation.ThreadObserver getThreadObserver(string parent, string id, Ice.Instrumentation.ThreadState s, Ice.Instrumentation.ThreadObserver obsv) { if(_threads.isEnabled()) { try { Ice.Instrumentation.ThreadObserver del = null; ThreadObserverI o = obsv is ThreadObserverI ? (ThreadObserverI)obsv : null; if(_delegate != null) { del = _delegate.getThreadObserver(parent, id, s, o != null ? o.getDelegate() : obsv); } return _threads.getObserver(new ThreadHelper(parent, id, s), obsv, del); } catch(Exception ex) { _metrics.getLogger().error("unexpected exception trying to obtain observer:\n" + ex); } } return null; } public Ice.Instrumentation.InvocationObserver getInvocationObserver(Ice.ObjectPrx prx, string operation, Dictionary ctx) { if(_invocations.isEnabled()) { try { Ice.Instrumentation.InvocationObserver del = null; if(_delegate != null) { del = _delegate.getInvocationObserver(prx, operation, ctx); } return _invocations.getObserver(new InvocationHelper(prx, operation, ctx), del); } catch(Exception ex) { _metrics.getLogger().error("unexpected exception trying to obtain observer:\n" + ex); } } return null; } public Ice.Instrumentation.DispatchObserver getDispatchObserver(Ice.Current c, int size) { if(_dispatch.isEnabled()) { try { Ice.Instrumentation.DispatchObserver del = null; if(_delegate != null) { del = _delegate.getDispatchObserver(c, size); } return _dispatch.getObserver(new DispatchHelper(c, size), del); } catch(Exception ex) { _metrics.getLogger().error("unexpected exception trying to obtain observer:\n" + ex); } } return null; } public void setObserverUpdater(Ice.Instrumentation.ObserverUpdater updater) { if(updater == null) { _connections.setUpdater(null); _threads.setUpdater(null); } else { _connections.setUpdater(updater.updateConnectionObservers); _threads.setUpdater(updater.updateThreadObservers); } if(_delegate != null) { _delegate.setObserverUpdater(updater); } } public MetricsAdminI getFacet() { return _metrics; } readonly private MetricsAdminI _metrics; readonly private Ice.Instrumentation.CommunicatorObserver _delegate; readonly private ObserverFactoryWithDelegate _connections; readonly private ObserverFactoryWithDelegate _dispatch; readonly private ObserverFactoryWithDelegate _invocations; readonly private ObserverFactoryWithDelegate _threads; readonly private ObserverFactoryWithDelegate _connects; readonly private ObserverFactoryWithDelegate _endpointLookups; } }