/// <summary> /// Formats as block-formatted string of an <see cref="IBgpPeers" />. /// </summary> /// <param name="bgpPeers">The data to format.</param> /// <returns>The formatted string.</returns> public string Format(IBgpPeers bgpPeers) { if (bgpPeers == null) { return("<null>"); } StringBuilder returnBuilder = new StringBuilder((bgpPeers.Details?.Count ?? 1) * 128); returnBuilder.Append("BGP Peers:"); if (bgpPeers.Details.Count == 0) { returnBuilder.Append(" No BGP peers found."); } else { foreach (var item in bgpPeers.Details) { returnBuilder.AppendLine().AppendLine(SnmpAbstraction.IndentLines(this.Format(item))); } } return(returnBuilder.ToString()); }
/// <summary> /// Copy-construct from an IBgpPeers. /// </summary> /// <param name="bgpPeers">The source to copy.</param> public BgpPeersStoreOnlyContainer(IBgpPeers bgpPeers) { if (bgpPeers is null) { throw new ArgumentNullException(nameof(bgpPeers), "bgpPeers is null when copy-construcing a StoreOnly container"); } this.detailsBacking = bgpPeers.Details.Select(p => new BgpPeerStoreOnlyContainer(p) as IBgpPeer).ToList(); this.DeviceAddress = bgpPeers.DeviceAddress; this.DeviceModel = bgpPeers.DeviceModel; this.QueryDuration = bgpPeers.QueryDuration; }
/// <summary> /// Calls the IAquiredDataHandler.RecordDetailsInDatabaseAsync for all configured handlers. /// </summary> private void SendResultsToDataHandlers(IHamnetDbHost host, IBgpPeers peers, DateTime queryTime) { foreach (IAquiredDataHandler handler in this.dataHandlers) { try { handler.RecordDetailsInDatabaseAsync(host, peers, queryTime); } catch (Exception ex) { this.logger.LogError($"Excpetion recording failed query at handler {handler.Name}: {ex.Message}"); } } }
/// <inheritdoc /> public Task RecordDetailsInDatabaseAsync(IHamnetDbHost host, IBgpPeers peers, DateTime queryTime) { return(Task.Run(() => { try { this.RecordDetailsInDatabase(host, peers, queryTime); } catch (Exception ex) { // we don not want to throw from an async task log.Error($"Caught and ignored exception in async recording of BGP details for {host.Address} ({host.Name}) @ {queryTime}: {ex.Message}", ex); } })); }
/// <inheritdoc /> public void RecordDetailsInDatabase(IHamnetDbHost host, IBgpPeers peers, DateTime queryTime) { using (var databaseContext = QueryResultDatabaseProvider.Instance.CreateContext()) { using (var transaction = databaseContext.Database.BeginTransaction()) { this.DoRecordBgpDetailsInDatabase(databaseContext, host, peers, DateTime.UtcNow); this.DoDeleteFailingBgpQuery(databaseContext, host); databaseContext.SaveChanges(); transaction.Commit(); } } }
/// <summary> /// Records the BGP results in the database. /// </summary> /// <param name="databaseContext">The database context to work with.</param> /// <param name="host">The host data of the query.</param> /// <param name="bgpPeers">The BGP peers to record.</param> /// <param name="queryTime">The time of the data aquisition (recorded with the data).</param> private void DoRecordBgpDetailsInDatabase(QueryResultDatabaseContext databaseContext, IHamnetDbHost host, IBgpPeers bgpPeers, DateTime queryTime) { var localAdressToSearch = host.Address.ToString(); foreach (var item in bgpPeers.Details) { var remoteAdressToSearch = item.RemoteAddress.ToString(); var peerEntry = databaseContext.BgpPeers.SingleOrDefault(p => (p.LocalAddress == localAdressToSearch) && (p.RemoteAddress == remoteAdressToSearch)); if (peerEntry == null) { peerEntry = new BgpPeerData { LocalAddress = localAdressToSearch, LocalCallsign = host.Callsign.ToUpperInvariant(), RemoteAddress = remoteAdressToSearch }; databaseContext.BgpPeers.Add(peerEntry); } peerEntry.LocalCallsign = host.Callsign.ToUpperInvariant(); peerEntry.PeeringName = item.Name; peerEntry.PeeringState = item.State; peerEntry.PrefixCount = item.PrefixCount; peerEntry.Uptime = item.Uptime.ToString(); peerEntry.TimeStampString = queryTime.ToUniversalTime().ToString("yyyy-MM-ddTHH\\:mm\\:sszzz"); peerEntry.UnixTimeStamp = (ulong)queryTime.ToUniversalTime().Subtract(Program.UnixTimeStampBase).TotalSeconds; } }
/// <summary> /// Formats a generic object if it's of one of the supported types. /// </summary> /// <param name="someObject">The object to format.</param> /// <returns>The formatted text.</returns> public string Format(object someObject) { if (someObject == null) { return("<null>"); } IDeviceSystemData asDevSysData = someObject as IDeviceSystemData; if (asDevSysData != null) { return(this.Format(asDevSysData)); } IInterfaceDetails asIfDetails = someObject as IInterfaceDetails; if (asIfDetails != null) { return(this.Format(asIfDetails)); } IInterfaceDetail asIfDetail = someObject as IInterfaceDetail; if (asIfDetail != null) { return(this.Format(asIfDetail)); } IWirelessPeerInfos asWiPeerInfos = someObject as IWirelessPeerInfos; if (asWiPeerInfos != null) { return(this.Format(asWiPeerInfos)); } IWirelessPeerInfo asWiPeerInfo = someObject as IWirelessPeerInfo; if (asWiPeerInfo != null) { return(this.Format(asWiPeerInfo)); } ILinkDetails asLinkDetails = someObject as ILinkDetails; if (asLinkDetails != null) { return(this.Format(asLinkDetails)); } IBgpPeers asBgpPeers = someObject as IBgpPeers; if (asBgpPeers != null) { return(this.Format(asBgpPeers)); } IBgpPeer asBgpPeer = someObject as IBgpPeer; if (asBgpPeer != null) { return(this.Format(asBgpPeer)); } ITracerouteResult asTracerouteResult = someObject as ITracerouteResult; if (asTracerouteResult != null) { return(this.Format(asTracerouteResult)); } ITracerouteHop asTracerouteHop = someObject as ITracerouteHop; if (asTracerouteHop != null) { return(this.Format(asTracerouteHop)); } // fallback: call the object's ToString return(someObject.ToString()); }
/// <inheritdoc /> public void RecordDetailsInDatabase(IHamnetDbHost host, IBgpPeers peers, DateTime queryTime) { lock (this.recordingLock) { this.CreateNewPayload(); var localHostCall = host.Callsign.ToUpperInvariant(); var localHostAddress = host.Address.ToString(); var queryUniversalTime = queryTime.ToUniversalTime(); foreach (var item in peers) { var remoteAs = item.RemoteAs.ToString(); string remoteSubnet = null; if (this.hamnetDbPoller.TryGetSubnetOfHost(item.RemoteAddress, out IHamnetDbSubnet hamentDbSubnet)) { remoteSubnet = hamentDbSubnet.Subnet.ToString(); } if (this.currentPayload == null) { this.CreateNewPayload(); } this.currentPayload.Add( new LineProtocolPoint( InfluxBgpLinkUptimeDatapointName, new Dictionary <string, object> { { InfluxValueKey, item.Uptime } }, new Dictionary <string, string> { { InfluxPeeringNameTagName, item.Name }, { InfluxSubnetTagName, remoteSubnet }, { InfluxHostTagName, localHostAddress }, { InfluxCallTagName, localHostCall }, { InfluxRemoteAsTagName, remoteAs }, { InfluxDescriptionTagName, $"BGP Link Uptime {item.LocalAddress} <-> {item.RemoteAddress}" } }, queryUniversalTime)); this.currentPayload.Add( new LineProtocolPoint( InfluxBgpLinkStateDatapointName, new Dictionary <string, object> { { InfluxValueKey, (int)item.StateEnumeration }, { InfluxStringValueKey, item.StateEnumeration } }, new Dictionary <string, string> { { InfluxPeeringNameTagName, item.Name }, { InfluxSubnetTagName, remoteSubnet }, { InfluxHostTagName, localHostAddress }, { InfluxCallTagName, localHostCall }, { InfluxRemoteAsTagName, remoteAs }, { InfluxDescriptionTagName, $"BGP State {item.LocalAddress} <-> {item.RemoteAddress}" } }, queryUniversalTime)); this.currentPayload.Add( new LineProtocolPoint( InfluxBgpPrefixCountDatapointName, new Dictionary <string, object> { { InfluxValueKey, item.PrefixCount } }, new Dictionary <string, string> { { InfluxPeeringNameTagName, item.Name }, { InfluxSubnetTagName, remoteSubnet }, { InfluxHostTagName, localHostAddress }, { InfluxCallTagName, localHostCall }, { InfluxRemoteAsTagName, remoteAs }, { InfluxDescriptionTagName, $"BGP Prefixes from {item.LocalAddress} to {item.RemoteAddress}" } }, queryUniversalTime)); } this.SendCurrentPayload(); } }