public void FlightRecorder_PassThru_SysLogProvider() { // Verify that the ISysLogProvider implementation works. Queue <FlightEvent> queue = new Queue <FlightEvent>(); ISysLogProvider orgProvider = SysLog.LogProvider; try { FlightEvent flightEvent; using (var recorder = new FlightRecorder(evt => queue.Enqueue(evt))) { SysLog.LogProvider = recorder; SysLog.LogError("Test Error"); SysLog.LogWarning("Test Warning"); SysLog.LogInformation("Test Information"); SysLog.Flush(); Assert.AreEqual(3, queue.Count); flightEvent = queue.Dequeue(); Assert.AreEqual("SysLog:Error", flightEvent.Operation); Assert.IsTrue(flightEvent.Details.Contains("Test Error")); Assert.IsTrue(flightEvent.IsError); flightEvent = queue.Dequeue(); Assert.AreEqual("SysLog:Warning", flightEvent.Operation); Assert.IsTrue(flightEvent.Details.Contains("Test Warning")); Assert.IsFalse(flightEvent.IsError); flightEvent = queue.Dequeue(); Assert.AreEqual("SysLog:Information", flightEvent.Operation); Assert.IsTrue(flightEvent.Details.Contains("Test Information")); Assert.IsFalse(flightEvent.IsError); // Verify that system events actually serialize exception // and stack trace related information. try { throw new AssertException(); } catch (Exception e) { SysLog.LogException(e); SysLog.Flush(); flightEvent = queue.Dequeue(); Assert.AreEqual("SysLog:Exception", flightEvent.Operation); Assert.IsTrue(flightEvent.Details.Contains("AssertException")); } } } finally { SysLog.LogProvider = orgProvider; } }
private static int refCount = 0; // Start() reference count /// <summary> /// Used by services and applications to start the <see cref="ChannelHost" />, /// using the result of <see cref="Assembly" />.<see cref="Assembly.GetEntryAssembly" /> /// to determine the location of the application configuration file. /// </summary> /// <remarks> /// <para> /// Calls to this method may be nested. A reference count is maintained and only /// the first call will actually perform any initialization. /// </para> /// <note> /// All successful calls to <see cref="Start()" /> must eventually be matched with /// a call to <see cref="Stop" /> global state including the underlying LillTek /// <see cref="MsgRouter" /> will be released properly. /// </note> /// </remarks> public static void Start() { using (TimedLock.Lock(SyncRoot)) { if (refCount == 0) { if (!Helper.IsInitialized) { Assembly entryAssembly = Assembly.GetEntryAssembly(); if (entryAssembly == null) { SysLog.LogWarning("Unable obtain the entry assembly via Assembly.GetEntryAssembly(). " + "The application's LillTek configuration settings will not be available. " + "You may call LillTek.ServiceModel.ChannelHost.Start(Assembly) with a valid " + "assembly during application initialization to correct this."); entryAssembly = Assembly.GetExecutingAssembly(); // Use the current assembly instead } Helper.InitializeApp(entryAssembly); } RegisterMsgTypes(); MsgRouter.StartGlobal(); } refCount++; } }
/// <summary> /// Constructor. /// </summary> /// <param name="packet">The switch packet.</param> internal SwitchEventReceivedArgs(SwitchPacket packet) { ArgCollection properties; ArgCollection variables; string eventName; this.TimeUtc = packet.Headers.Get("Event-Date-GMT", DateTime.MinValue); if (packet.Headers.TryGetValue("Event-Name", out eventName)) { this.EventName = eventName; this.EventCode = SwitchHelper.ParseEventCode(eventName); } else { // I don't think this should ever happen. SysLog.LogWarning("SwitchConnection received an event without an [Event-Name] property."); this.EventName = string.Empty; this.EventCode = default(SwitchEventCode); } SwitchHelper.ProcessEventProperties(packet.Headers, out properties, out variables); this.Properties = properties; this.Variables = variables; this.ContentType = packet.ContentType; this.Content = packet.Content; this.ContentText = packet.ContentText; }
/// <summary> /// Reflects an assembly looking for public classes that implement <see cref="ISwitchSubcommand" /> /// and registers any found with the switch command dispatch subsystem. /// </summary> /// <param name="assembly">The source assembly.</param> /// <remarks> /// <note> /// The application may call this method <b>only</b> when executing within its /// <see cref="SwitchApp.Main" /> method. /// </note> /// <para> /// This method registers the name of the class without the namespace and /// also stripping the "Command" suffix if present as the name of the /// subcommand. /// </para> /// <note> /// Registered subcommands are case insensitive. /// </note> /// </remarks> public static void RegisterAssemblySubcommands(Assembly assembly) { if (!SwitchApp.InMain) { throw new InvalidOperationException("[RegisterAssemblySubcommands] may be called only from within the SwitchApp.Main() method."); } foreach (var type in assembly.GetTypes()) { if (!type.IsPublic || !typeof(ISwitchSubcommand).IsAssignableFrom(type)) { continue; } string subcommand = type.Name.ToLowerInvariant(); Type existing; if (subcommand.EndsWith("command")) { subcommand = subcommand.Substring(0, subcommand.Length - "command".Length); } if (subcommandHandlers.TryGetValue(subcommand, out existing)) { SysLog.LogWarning("NeonSwitch subcommand conflict. Subcommand class [{0}] conflicts with [{1}]. [{1}] will be used.", type.FullName, existing.FullName); continue; } subcommandHandlers.Add(subcommand, type); } }
/// <summary> /// Verifies that a <see cref="ChannelState" /> code passed is one of the known states. /// </summary> /// <param name="channelState">The channel state code being tested.</param> /// <returns> /// The same state code if it is known to the current implementation, /// <see cref="ChannelState.None" /> otherwise. /// </returns> /// <remarks> /// A warning will be logged if the state code is not known. /// </remarks> public static ChannelState ValidateChannelState(ChannelState channelState) { switch (channelState) { case ChannelState.New: case ChannelState.Initialized: case ChannelState.Routing: case ChannelState.SoftExecute: case ChannelState.Execute: case ChannelState.ExchangingMedia: case ChannelState.Park: case ChannelState.ConsumingMedia: case ChannelState.Hibernate: case ChannelState.Reset: case ChannelState.Hangup: case ChannelState.Reporting: case ChannelState.Destroy: case ChannelState.None: return(channelState); default: SysLog.LogWarning("Unexpected channel state [{0}].", channelState); return(ChannelState.None); } }
/// <summary> /// Removes the performance counters from the system if present. /// </summary> /// <remarks> /// <note> /// The calling process must have sufficient rights to perform this operation. If /// this is not the case, then this method will fail silently. /// </note> /// </remarks> public void Uninstall() { foreach (var counter in counters.Values) { counter.Close(); } if (!PerfCounter.ProcessLocalOnly && PerformanceCounterCategory.Exists(categoryName)) { try { PerformanceCounterCategory.Delete(categoryName); } catch (SecurityException) { SysLog.LogWarning("Process does not have sufficient rights to uninstall performance counters."); return; } catch (UnauthorizedAccessException) { SysLog.LogWarning("Process does not have sufficient rights to uninstall performance counters."); return; } catch (Exception e) { SysLog.LogException(e, "Process was not able to uninstall performance counters."); return; } } installed = false; }
/// <summary> /// Opens the topology instance in server mode. /// </summary> /// <param name="router">The message router to be used by the cluster.</param> /// <param name="dynamicScope">The dynamic scope name.</param> /// <param name="target">The target object whose dynamic message handlers are to be registered (or <c>null</c>).</param> /// <param name="clusterEP">The cluster's logical endpoint.</param> /// <param name="args">Topology implementation specific parameters (ignored for this implementation).</param> /// <remarks> /// <para> /// This method also registers the dynamic message handlers that case-insensitvely /// match the dynamicScope parameter passed that are found within the /// target object passed with the router's message dispatcher, after performing /// any necessary munging of their message endpoints. This is done by /// matching the dynamicScope parameter passed against the <see cref="MsgHandler.DynamicScope" /> /// property in the <see cref="MsgHandler" /> attribute tagging the message handler. /// </para> /// <para> /// The matching message handler endpoints will be set to clusterEP. /// </para> /// </remarks> public virtual void OpenServer(MsgRouter router, string dynamicScope, MsgEP clusterEP, object target, ArgCollection args) { if (!clusterEP.IsLogical) { throw new ArgumentException(TopologyHelper.ClusterEPNotLogicalMsg); } if (!router.EnableP2P) { SysLog.LogWarning(NoP2PMsg); } this.router = router; this.instanceID = Helper.NewGuid(); this.clusterEP = clusterEP; this.broadcastEP = new MsgEP(clusterEP, "*"); this.instanceEP = new MsgEP(clusterEP, Helper.NewGuid().ToString()); this.isClient = false; if (target != null) { router.Dispatcher.AddTarget(target, dynamicScope, this, null); } OnLogicalChange(); // Forces the initial load of the instance EPs }
/// <summary> /// Opens the topology instance in client mode. /// </summary> /// <param name="router">The message router to be used by the cluster.</param> /// <param name="clusterEP">The cluster's logical endpoint.</param> /// <param name="args">Topology implementation specific parameters (ignored for this implementation).</param> /// <remarks> /// </remarks> public virtual void OpenClient(MsgRouter router, MsgEP clusterEP, ArgCollection args) { if (!clusterEP.IsLogical) { throw new ArgumentException(TopologyHelper.ClusterEPNotLogicalMsg); } if (!router.EnableP2P) { SysLog.LogWarning(NoP2PMsg); } this.router = router; this.instanceID = Helper.NewGuid(); this.clusterEP = clusterEP; this.broadcastEP = new MsgEP(clusterEP, "*"); this.instanceEP = null; this.isClient = true; ArgCollection argsCopy; argsCopy = args.Clone(); argsCopy["topology-type"] = TopologyHelper.SerializeType(this.GetType()); serialized = argsCopy.ToString(); OnLogicalChange(); // Forces the initial load of the instance EPs }
public void OnMsg(AuthControlMsg msg) { try { using (TimedLock.Lock(this)) { if (!isOpen) { return; } switch (msg.Command) { case "auth-key-update": publicKey = null; // This will force the retrieval of a new key break; // on the next auth request case "cache-clear": if (cache != null) { cache.Clear(); } break; case "cache-remove-realm": if (cache != null) { CacheRemove(msg.Get("realm", string.Empty) + "\t"); } break; case "lock-account": case "cache-remove-account": if (cache != null) { CacheRemove(msg.Get("realm", string.Empty) + "\t" + msg.Get("account", string.Empty) + "\t"); } break; default: SysLog.LogWarning("Unexpected authentication control command [{0}].", msg.Command); break; } } } catch (Exception e) { SysLog.LogException(e); } }
/// <summary> /// The application worker thread. /// </summary> private void AppThread() { // All NeonSwitch applications (except for the core service) need to wait for // the core to be initialized before the application can be started. We're // going to spin here until the core indicates that it's ready. var warningTimer = new PolledTimer(TimeSpan.FromSeconds(60)); if (!SwitchApp.IsCore) { while (true) { if (String.Compare(Switch.GetGlobal(SwitchGlobal.NeonSwitchReady), "true", true) == 0) { break; } if (warningTimer.HasFired) { warningTimer.Disable(); SysLog.LogWarning("NeonSwitch application [{0}] has waited [{1}] for the core NeonSwitch service to start.", SwitchApp.Name, warningTimer.Interval); } Thread.Sleep(TimeSpan.FromSeconds(1)); } } // Continue performing wwitch initialization. We needed to wait until after // the NeonSwitch core service started before calling this. Switch.Initialize(); // Call the application entry point so it can initalize itself. try { InMain = true; Main(); InMain = false; mainCalled = true; } catch (Exception e) { SysLog.LogException(e, "The NeonSwitch application's Main() method threw an exception."); throw; } finally { InMain = false; } // NeonSwitch handles the event dispatching. Switch.EventLoop(); }
/// <summary> /// Installs the set of performance counters to the system if necessary. /// </summary> /// <remarks> /// <note> /// The calling process must have sufficient rights to perform this operation. If /// this is not the case, then this method will fail silently. /// </note> /// </remarks> public void Install() { if (!enabled || installed) { return; } // Install the counters as necessary. if (!PerfCounter.ProcessLocalOnly && !PerformanceCounterCategory.Exists(categoryName)) { var creationData = new CounterCreationDataCollection(); foreach (var counter in counters.Values.OrderBy(c => c.Name.ToLowerInvariant())) { creationData.Add(new CounterCreationData(counter.Name, counter.Help, counter.Type)); } try { PerformanceCounterCategory.Create(categoryName, categoryHelp, multiInstance ? PerformanceCounterCategoryType.MultiInstance : PerformanceCounterCategoryType.SingleInstance, creationData); } catch (InvalidOperationException e) { // We can see this error sometimes when multiple processes attempt // to create the performance counters at the same time and one // attempt failes because the counters already exist. We're going // log and ignore this. SysLog.LogException(e, "This can happen if more than one process or thread is trying to register performance counters at the same time. This is probably not a problem."); } catch (SecurityException) { SysLog.LogWarning("Process does not have sufficient rights to install performance counters. Falling back to simulated local performance counters."); installFailed = true; } catch (UnauthorizedAccessException) { SysLog.LogWarning("Process does not have sufficient rights to install performance counters. Falling back to simulated local performance counters."); installFailed = true; } catch (Exception e) { SysLog.LogException(e, "Process was unable to install performance counters. Falling back to simulated local performance counters."); installFailed = true; } } // Mark the set as installed. installed = true; }
/// <summary> /// Loads the requested environment variable, logging a warning if the variable is not set. /// </summary> /// <param name="name">The variable name.</param> /// <returns>The variable's value or the empty string.</returns> private static string GetVar(string name) { var value = System.Environment.GetEnvironmentVariable(name); if (string.IsNullOrWhiteSpace(value)) { SysLog.LogWarning("AzureHelper.Initialize: Environment variable [{0}] is not set.", name); } return(value); }
/// <summary> /// Returns the low-level FreeSWITCH string corresponding to a <see cref="SwitchEventCode" />. /// </summary> /// <param name="switchEvent">The switch event code.</param> /// <returns>The corresponding string or <b>SWITCH_EVENT_CUSTOM</b> if the code is unknown.</returns> public static string GetEventCodeString(SwitchEventCode switchEvent) { string eventString; if (!switchEventToString.TryGetValue(switchEvent, out eventString)) { SysLog.LogWarning("Unexpected switch event code [{0}].", switchEvent); eventString = switchEventToString[SwitchEventCode.Custom]; } return(eventString); }
/// <summary> /// Returns the low-level FreeSWITCH string corresponding to a <see cref="SwitchLogLevel" />. /// </summary> /// <param name="logLevel">The log level.</param> /// <returns>The corresponding string or <b>NONE</b> if the code is unknown.</returns> public static string GetSwitchLogLevelString(SwitchLogLevel logLevel) { string logLevelString; if (!switchLogLevelToString.TryGetValue(logLevel, out logLevelString)) { SysLog.LogWarning("Unexpected channel log level [{0}].", logLevel); logLevelString = switchLogLevelToString[SwitchLogLevel.None]; } return(logLevelString); }
/// <summary> /// Parses the low-level FreeSWITCH log level string into a <see cref="SwitchLogLevel" /> value. /// </summary> /// <param name="value">The FreeSWITCH channel state string.</param> /// <returns>The parsed <see cref="SwitchLogLevel" /> or <see cref="SwitchLogLevel.None" /> /// if the value could not be parsed. /// </returns> public static SwitchLogLevel ParseSwitchLogLevel(string value) { SwitchLogLevel logLevel; if (!stringToSwitchLogLevel.TryGetValue(value, out logLevel)) { SysLog.LogWarning("Unexpected FreeSWITCH log level [{0}].", value); logLevel = SwitchLogLevel.None; } return(logLevel); }
/// <summary> /// Returns the low-level FreeSWITCH string corresponding to a <see cref="ChannelState" />. /// </summary> /// <param name="channelState">The channel state code.</param> /// <returns>The corresponding string or <b>NONE</b> if the code is unknown.</returns> public static string GetChannelStateString(ChannelState channelState) { string stateString; if (!channelStateToString.TryGetValue(channelState, out stateString)) { SysLog.LogWarning("Unexpected channel state code [{0}].", channelState); stateString = channelStateToString[ChannelState.None]; } return(stateString); }
/// <summary> /// Returns the low-level FreeSWITCH string corresponding to a <see cref="CallDirection" />. /// </summary> /// <param name="direction">The direction code.</param> /// <returns>The corresponding string or <see cref="Empty" /> if the code is unknown.</returns> public static string GetSwitchHangupReasonString(CallDirection direction) { string directionString; if (!callDirectionToString.TryGetValue(direction, out directionString)) { SysLog.LogWarning("Unexpected call direction code [{0}].", direction); directionString = string.Empty; } return(directionString); }
/// <summary> /// Parses the low-level FreeSWITCH call direction string to a <see cref="CallDirection" /> value. /// </summary> /// <param name="directionString">The FreeSWITCH direction string.</param> /// <returns> /// The parsed <see cref="CallDirection" /> or <see cref="CallDirection.Unknown" /> /// if the value could not be parsed. /// </returns> public static CallDirection ParseCallDirection(string directionString) { CallDirection direction; if (!stringToCallDirection.TryGetValue(directionString, out direction)) { SysLog.LogWarning("Unexpected FreeSWITCH call direction [{0}].", directionString); direction = CallDirection.Unknown; } return(direction); }
/// <summary> /// Returns the low-level FreeSWITCH string corresponding to a <see cref="SwitchHangupReason" />. /// </summary> /// <param name="reason">The hangup reason code.</param> /// <returns>The corresponding string or <b>NONE</b> if the code is unknown.</returns> public static string GetSwitchHangupReasonString(SwitchHangupReason reason) { string reasonString; if (!switchHangupReasonToString.TryGetValue(reason, out reasonString)) { SysLog.LogWarning("Unexpected switch hangup reason code [{0}].", reason); reasonString = switchHangupReasonToString[SwitchHangupReason.None]; } return(reasonString); }
/// <summary> /// Parses the low-level FreeSWITCH hangup reason <see cref="SwitchHangupReason" /> value. /// </summary> /// <param name="reasonString">The FreeSWITCH hangup reason.</param> /// <returns> /// The parsed <see cref="SwitchHangupReason" /> or <see cref="SwitchHangupReason.None" /> /// if the value could not be parsed. /// </returns> public static SwitchHangupReason ParseHangupReason(string reasonString) { SwitchHangupReason reason; if (!stringToSwitchHangupReason.TryGetValue(reasonString, out reason)) { SysLog.LogWarning("Unexpected FreeSWITCH hangup reason [{0}].", reasonString); reason = SwitchHangupReason.None; } return(reason); }
/// <summary> /// Parses the low-level FreeSWITCH event name passed into a <see cref="SwitchEventCode" /> value. /// </summary> /// <param name="value">The FreeSWITCH event name.</param> /// <returns> /// The parsed <see cref="SwitchEventCode" /> or <see cref="SwitchEventCode.Custom" /> /// if the value could not be parsed. /// </returns> public static SwitchEventCode ParseEventCode(string value) { SwitchEventCode switchEvent; if (!stringToSwitchEvent.TryGetValue(value, out switchEvent)) { SysLog.LogWarning("Unexpected FreeSWITCH event [{0}].", value); switchEvent = SwitchEventCode.Custom; } return(switchEvent); }
/// <summary> /// Parses the low-level FreeSWITCH channel state string into a <see cref="ChannelState" /> value. /// </summary> /// <param name="value">The FreeSWITCH channel state string.</param> /// <returns>The parsed <see cref="ChannelState" /> or <see cref="ChannelState.None" /> /// if the value could not be parsed. /// </returns> public static ChannelState ParseChannelState(string value) { ChannelState channelState; if (!stringToChannelState.TryGetValue(value, out channelState)) { SysLog.LogWarning("Unexpected FreeSWITCH channel state [{0}].", value); channelState = ChannelState.None; } return(channelState); }
/// <summary> /// Performs a best efforts recovery of orphaned transactions. /// </summary> private void Recover() { var orphans = log.GetOrphanTransactions(); var context = new UpdateContext(this, true, false, false, Guid.Empty); IOperation operation; SysLog.LogWarning("Recovering [{0}] transactions for [{1}].", orphans.Count, resource.Name); Trace(0, "Begin Recovery", null); resource.BeginRecovery(context); for (int i = 0; i < orphans.Count; i++) { IOperationLog opLog = log.OpenOperationLog(orphans[i]); context.TransactionID = opLog.TransactionID; if (opLog.Mode == OperationLogMode.Redo) { if (resource.BeginRedo(context)) { foreach (ILogPosition pos in opLog.GetPositions(false)) { operation = opLog.Read(resource, pos); Trace(0, "Redo: " + operation.Description, "ID=" + context.TransactionID.ToString()); resource.Redo(context, operation); } } resource.EndRedo(context); } else { if (resource.BeginUndo(context)) { foreach (ILogPosition pos in opLog.GetPositions(true)) { operation = opLog.Read(resource, pos); Trace(0, "Undo: " + operation.Description, "ID=" + context.TransactionID.ToString()); resource.Undo(context, opLog.Read(resource, pos)); } } resource.EndUndo(context); } log.CloseOperationLog(opLog); } context.TransactionID = Guid.Empty; resource.EndRecovery(context); Trace(0, "End Recovery", null); }
/// <summary> /// Starts the gateway and the associated <see cref="SipCore" /> if it has not /// already been started. /// </summary> /// <remarks> /// <note><see cref="SipMssGateway" /> instances cannot be restarted.</note> /// </remarks> public void Start() { using (TimedLock.Lock(core)) { if (isRunning) { throw new InvalidOperationException("MSS Gateway is already running."); } if (isUsed) { throw new InvalidOperationException("Cannot restart a MSS Gateway."); } isRunning = true; isUsed = true; } Helper.GetNetworkInfo(out localAddress, out localSubnet); b2bua = new SipB2BUserAgent <object>(core); b2bua.InviteRequestReceived += new SipB2BUAEventDelegate <object>(OnInviteRequestReceived); b2bua.InviteResponseReceived += new SipB2BUAEventDelegate <object>(OnInviteResponseReceived); b2bua.SessionConfirmed += new SipB2BUAEventDelegate <object>(OnSessionConfirmed); b2bua.SessionClosing += new SipB2BUAEventDelegate <object>(OnSessionClosing); b2bua.ClientRequestReceived += new SipB2BUAEventDelegate <object>(OnClientRequestReceived); b2bua.ServerRequestReceived += new SipB2BUAEventDelegate <object>(OnServerRequestReceived); b2bua.ClientResponseReceived += new SipB2BUAEventDelegate <object>(OnClientResponseReceived); b2bua.ServerResponseReceived += new SipB2BUAEventDelegate <object>(OnServerResponseReceived); if (!core.IsRunning) { core.Start(); } b2bua.Start(); if (settings.Register.Length > 1) { SysLog.LogWarning("MSS Gateway currently supports only one registration URI. Only the first URI will be registered."); } if (settings.Register.Length > 0) { core.StartAutoRegistration((string)settings.TrunkUri, (string)settings.Register[0]); } }
/// <summary> /// Attempts to return the server side transaction ID from the message. This is /// the <b>branch</b> parameter from the top-most <b>Via</b> header. /// </summary> /// <param name="transactionID">Returns as the transaction ID on success.</param> /// <returns><b><c>true</c> if the transaction ID was returned.</b></returns> /// <remarks> /// <para> /// Transaction IDs are formed from the "branch" parameter of the /// topmost "Via" header, plus the "sent-by" parameter on the "Via" (if present) /// plus the method as upper case (except for the ACK method which maps to INVITE) /// </para> /// <para> /// This method also implements the alternative RFC 2543 compatible procedure /// if the Via branch parameter doesn't start with the magic cookie (not /// implemented yet). /// </para> /// <para> /// See RFC 3261 17.2.3 on page 138 for more information. /// </para> /// </remarks> public bool TryGetTransactionID(out string transactionID) { SipHeader via; SipViaValue viaValue; string branch; string sentBy; transactionID = null; via = base[SipHeader.Via]; if (via == null) { return(false); } viaValue = new SipViaValue(via.Text); branch = viaValue.Branch; if (branch == null || !branch.StartsWith("z9hG4bK")) { SysLog.LogWarning("SIP Request received with non-compliant Via branch parameter."); return(false); } transactionID = branch + ":"; sentBy = viaValue.SentBy; if (sentBy != null) { transactionID += sentBy; } transactionID += ":"; if (method == SipMethod.Ack) { transactionID += "INVITE"; } else { transactionID += methodText.ToUpper(); } return(true); }
/// <summary> /// Starts the transaction manager. /// </summary> /// <param name="resource">The <see cref="ITransactedResource" /> to be managed.</param> /// <param name="log">The unopened <see cref="ITransactionLog" /> implementation to be used.</param> /// <param name="recoverCorrupt">Pass as <c>true</c> if recovery of corrupt transaction logs should be attempted.</param> public void Start(ITransactedResource resource, ITransactionLog log, bool recoverCorrupt) { using (TimedLock.Lock(this)) { if (running) { throw new TransactionException("Transaction manager has already started for [{0}].", resource.Name); } switch (log.Open(this)) { case LogStatus.Ready: break; case LogStatus.Recover: this.resource = resource; this.log = log; Recover(); break; case LogStatus.Corrupt: if (!recoverCorrupt) { throw new TransactionException("Transaction log for [{0]] is corrupt.", resource.Name); } SysLog.LogWarning("Corrupt transaction log detected for [{0}]. Best efforts are being taken to recover.", resource.Name); Recover(); break; } this.running = true; this.resource = resource; this.log = log; this.transactions = new Dictionary <Guid, BaseTransaction>(); this.threadTransMap = new Dictionary <int, BaseTransaction>(); } }
/// <summary> /// Queues an email message for deliver, /// </summary> /// <param name="message">The outbound message.</param> /// <remarks> /// <note> /// This message will do nothing but log a warning if the agent was started /// with a <b>Any</b> network binding. /// </note> /// </remarks> public void Enqueue(MailMessage message) { // Generate a unique file name that will sort roughly in the order // that the messages were added to the queue so that messages were // are delivered to the relay server in rougly the order that the // were queued. string fileName = string.Format("{0}-{1}.msg", Helper.ToIsoDate(DateTime.UtcNow).Replace(':', '-'), Guid.NewGuid()); if (smtpServer.IsAny) { // Email transmission is disabled SysLog.LogWarning("Email transmission is disabled."); return; } using (var output = new EnhancedFileStream(Path.Combine(queueFolder, fileName), FileMode.Create, FileAccess.ReadWrite)) MailHelper.WriteMessage(output, message); }
private CallStack createdAt; // The stack at the time the context was created #endif /// <summary> /// Initializes the context with the connection string passed. /// </summary> /// <param name="connectionString">The connection string.</param> /// <remarks> /// See the .NET Framework documentation for information on the format /// of this parameter. /// </remarks> public SqlContext(string connectionString) { this.conString = connectionString; this.sqlCon = null; this.sqlTrans = null; this.transactions = new Stack(); this.nextSavePoint = 0; this.onStdError = null; this.retrying = false; this.isSqlAzure = null; #if TRACK this.lastCommand = string.Empty; this.createdAt = new CallStack(1, true); if (!traceWarning) { SysLog.LogWarning("LillTek.Data.SqlContext TRACE enabled."); traceWarning = true; } #endif }
/// <summary> /// Reads the operation from the specified position in the log. /// </summary> /// <param name="resource">The parent <see cref="ITransactedResource" /> responsible for deserializing the operation.</param> /// <param name="position">See the <see cref="ILogPosition" />.</param> /// <returns>The <see cref="IOperation" /> read from the log.</returns> public IOperation Read(ITransactedResource resource, ILogPosition position) { int cb; long recEndPos; string description; IOperation operation; using (TimedLock.Lock(this)) { if (file == null) { throw new TransactionException(ClosedMsg); } file.Position = ((FileLogPosition)position).Position; if (file.ReadInt32() != Magic) { throw new TransactionException(CorruptMsg); } cb = file.ReadInt32(); if (cb <= 0 || cb + file.Position > file.Length) { throw new TransactionException(CorruptMsg); } recEndPos = file.Position + cb; description = file.ReadString32(); operation = resource.ReadOperation(file); if (file.Position != recEndPos) { SysLog.LogWarning("ITransactedResource.ReadOperation() returned with an unexpected stream position."); file.Position = recEndPos; } return(operation); } }
/// <summary> /// Initializes the instance. /// </summary> /// <param name="name">The logical counter name.</param> /// <param name="help">Counter description.</param> /// <param name="type">The performance counter type.</param> public PerfCounter(string name, string help, PerformanceCounterType type) : this() { this.name = name; this.category = string.Empty; this.help = help; this.type = type; switch (type) { case PerformanceCounterType.NumberOfItems32: case PerformanceCounterType.NumberOfItems64: case PerformanceCounterType.RateOfCountsPerSecond32: case PerformanceCounterType.RateOfCountsPerSecond64: break; default: SysLog.LogWarning("Performance counter type [{0}] for counter [{1}] is not supported for process local counters. [NextValue()] will always return zero.", type, name); break; } }