private static string FormatMessage( DateTime timestamp, LogLevel logLevel, string caller, string message, Exception exception, EventId errorCode) { if (logLevel == LogLevel.Error) { message = "!!!!!!!!!! " + message; } string exc = LogFormatter.PrintException(exception); string msg = String.Format("[{0} {1}\t{2}\t{3}\t{4}]\t{5}\t{6}", LogFormatter.PrintDate(timestamp), //0 Thread.CurrentThread.ManagedThreadId, //1 logLevel.ToString(), //2 errorCode.ToString(), //3 caller, //4 message, //5 exc); //6 return(msg); }
private static void InternalUnobservedTaskExceptionHandler(object sender, UnobservedTaskExceptionEventArgs e) { var aggrException = e.Exception; var baseException = aggrException.GetBaseException(); var tplTask = (Task)sender; var contextObj = tplTask.AsyncState; var context = contextObj as ISchedulingContext; try { if (unobservedExceptionHandler != null) { unobservedExceptionHandler(context, baseException); } } finally { if (e.Observed) { logger.Info(ErrorCode.Runtime_Error_100311, "UnobservedExceptionsHandlerClass caught an UnobservedTaskException which was successfully observed and recovered from. BaseException = {0}. Exception = {1}", baseException.Message, LogFormatter.PrintException(aggrException)); } else { var errorStr = String.Format("UnobservedExceptionsHandlerClass Caught an UnobservedTaskException event sent by {0}. Exception = {1}", OrleansTaskExtentions.ToString((Task)sender), LogFormatter.PrintException(aggrException)); logger.Error(ErrorCode.Runtime_Error_100005, errorStr); logger.Error(ErrorCode.Runtime_Error_100006, "Exception remained UnObserved!!! The subsequent behavior depends on the ThrowUnobservedTaskExceptions setting in app config and .NET version."); } } }
public void Close() { if (this.logOutput == null) { return; // was already closed. } try { lock (this.lockObj) { if (this.logOutput == null) // was already closed. { return; } this.logOutput.Flush(); this.logOutput.Dispose(); this.logOutput = null; } } catch (Exception exc) { var msg = string.Format("Ignoring error closing log file {0} - {1}", this.logFileName, LogFormatter.PrintException(exc)); Console.WriteLine(msg); } finally { this.logOutput = null; this.logFileName = null; } }
public async Task <IndirectProbeResponse> ProbeIndirectly(SiloAddress target, TimeSpan probeTimeout, int probeNumber) { IndirectProbeResponse result; var healthScore = this.ActivationServices.GetRequiredService <LocalSiloHealthMonitor>().GetLocalHealthDegradationScore(DateTime.UtcNow); var probeResponseTimer = ValueStopwatch.StartNew(); try { var probeTask = this.ProbeInternal(target, probeNumber); await probeTask.WithTimeout(probeTimeout, exceptionMessage : $"Requested probe timeout {probeTimeout} exceeded"); result = new IndirectProbeResponse { Succeeded = true, IntermediaryHealthScore = healthScore, ProbeResponseTime = probeResponseTimer.Elapsed, }; } catch (Exception exception) { result = new IndirectProbeResponse { Succeeded = false, IntermediaryHealthScore = healthScore, FailureMessage = $"Encountered exception {LogFormatter.PrintException(exception)}", ProbeResponseTime = probeResponseTimer.Elapsed, }; } return(result); }
public static string FormatLogMessageToLegacyStyle( DateTime timestamp, Severity severity, LoggerType loggerType, string caller, string message, IPEndPoint myIPEndPoint, Exception exception, int errorCode, bool includeStackTrace) { if (severity == Severity.Error) { message = "!!!!!!!!!! " + message; } string ip = myIPEndPoint == null ? String.Empty : myIPEndPoint.ToString(); string exc = includeStackTrace ? LogFormatter.PrintException(exception) : LogFormatter.PrintExceptionWithoutStackTrace(exception); string msg = String.Format("[{0} {1,5}\t{2}\t{3}\t{4}\t{5}]\t{6}\t{7}", LogFormatter.PrintDate(timestamp), //0 Thread.CurrentThread.ManagedThreadId, //1 severity.ToString(), //2 errorCode, //3 caller, //4 ip, //5 message, //6 exc); //7 return(msg); }
private async Task PublishDomainExceptionAsync(IDomainExceptionMessage exception, CancellationToken token) { var publisher = _serviceProvider.GetService <IDomainExceptionMessagePublisher>(); try { await publisher.PublishAsync(exception, token); } catch (Exception e) { _logger.LogError($"Publishing domain exception has a exception: {LogFormatter.PrintException(e)}."); } }
public async Task <DomainEventResult> AppendAsync( IDomainEvent @event, CancellationToken token = default) { if ([email protected]()) { return(DomainEventResult.StorageFailed(@event.Id, $"The domain event: [{@event.Print()}] cannot be stored mysql state backend.")); } var domainEventRecord = DomainEventRecordPortAdapter.ToDomainEventRecord(@event, _binarySerializer); var parameters = DbParameterProvider.ReflectionParameters(domainEventRecord); var tables = _options.Tables.DomainEventOptions; var insertDomainEventIndexSql = $"INSERT INTO `{tables.DomainEventIndices}`(`DomainCommandId`,`DomainCommandType`,`DomainCommandVersion`,`AggregateRootId`,`AggregateRootType`,`AggregateRootVersion`,`AggregateRootGeneration`,`DomainEventId`,`DomainEventType`,`DomainEventVersion`,`DomainEventPayloadBytes`,`CreatedTimestamp`) VALUES(@DomainCommandId,@DomainCommandType,@DomainCommandVersion,@AggregateRootId,@AggregateRootType,@AggregateRootVersion,@AggregateRootGeneration,@DomainEventId,@DomainEventType,@DomainEventVersion,@DomainEventPayloadBytes,@CreatedTimestamp)"; var insertDomainEventSql = $"INSERT INTO `{tables.DomainEvents}`(`DomainEventId`,`Payload`) VALUES (@DomainEventId,@Payload)"; var maxNumErrorTries = 3; var maxExecutionTime = TimeSpan.FromSeconds(3); var expectedRows = 2; bool ErrorFilter(Exception exc, int attempt) { if (exc is MySqlException inner && inner.HasDuplicateEntry()) { _logger.LogWarning($"{domainEventRecord.AggregateRootType}: [Ignored]find duplicated domain event from mysql state backend:{inner.Message}."); return(false); } _logger.LogError($"Append domain event has unknown exception: {LogFormatter.PrintException(exc)}."); return(true); } var affectedRows = await AsyncExecutorWithRetries.ExecuteWithRetriesAsync(async attempt => { return(await _db.ExecuteAsync( $"{insertDomainEventIndexSql};{insertDomainEventSql};", command => command.Parameters.AddRange(parameters), token)); }, maxNumErrorTries, ErrorFilter, maxExecutionTime).ConfigureAwait(false); if (affectedRows != expectedRows) { return(DomainEventResult.StorageFailed(@event.Id, $"The affected rows returned MySql state backend is incorrect, expected: {expectedRows}, actual: {affectedRows}.")); } return(DomainEventResult.StorageSucceed(@event.Id)); }
private void DeployTestingSiloHost(TestingSiloOptions siloOptions, TestingClientOptions clientOptions) { siloInitOptions = siloOptions; clientInitOptions = clientOptions; AppDomain.CurrentDomain.UnhandledException += ReportUnobservedException; InitializeLogWriter(); try { string startMsg = "----------------------------- STARTING NEW UNIT TEST SILO HOST: " + GetType().FullName + " -------------------------------------"; WriteLog(startMsg); InitializeAsync(siloOptions, clientOptions).Wait(); UninitializeLogWriter(); Instance = this; } catch (TimeoutException te) { FlushLogToConsole(); throw new TimeoutException("Timeout during test initialization", te); } catch (Exception ex) { StopAllSilos(); Exception baseExc = ex.GetBaseException(); FlushLogToConsole(); if (baseExc is TimeoutException) { throw new TimeoutException("Timeout during test initialization", ex); } // IMPORTANT: // Do NOT re-throw the original exception here, also not as an internal exception inside AggregateException // Due to the way MS tests works, if the original exception is an Orleans exception, // it's assembly might not be loaded yet in this phase of the test. // As a result, we will get "MSTest: Unit Test Adapter threw exception: Type is not resolved for member XXX" // and will loose the original exception. This makes debugging tests super hard! // The root cause has to do with us initializing our tests from Test constructor and not from TestInitialize method. // More details: http://dobrzanski.net/2010/09/20/mstest-unit-test-adapter-threw-exception-type-is-not-resolved-for-member/ throw new Exception( string.Format("Exception during test initialization: {0}", LogFormatter.PrintException(baseExc))); } }
public void OnException(ExceptionContext context) { if (context.Exception is ApiDomainException domainException) { //var aggregateMessage = domainException.Messages == null // ? context.Exception.Message // : JsonConvert.SerializeObject(domainException.Messages); //_logger.LogError(new EventId(context.Exception.HResult), // context.Exception, // aggregateMessage); var result = ApiErrorResult.BadRequest(domainException.Messages ?? new[] { context.Exception.Message }); context.Result = new BadRequestObjectResult(result); context.HttpContext.Response.StatusCode = StatusCodes.Status400BadRequest; } else { _logger.LogError(new EventId(context.Exception.HResult), context.Exception, context.Exception.Message); object devMessage = null; if (_env.IsDevelopment()) { devMessage = LogFormatter.PrintException(context.Exception); } var result = ApiExceptionResult.InternalServerError(new[] { "An server error occur." }, devMessage); context.Result = new InternalServerErrorObjectResult(result); context.HttpContext.Response.StatusCode = StatusCodes.Status500InternalServerError; } context.ExceptionHandled = true; }
private static string FormatLogMessage_Impl( DateTime timestamp, Severity severity, LoggerType loggerType, string caller, string message, IPEndPoint myIPEndPoint, Exception exception, int errorCode, bool includeStackTrace) { if (severity == Severity.Error) { message = "!!!!!!!!!! " + message; } string ip = myIPEndPoint == null ? String.Empty : myIPEndPoint.ToString(); if (loggerType.Equals(LoggerType.Grain)) { // Grain identifies itself, so I don't want an additional long string in the prefix. // This is just a temporal solution to ease the dev. process, can remove later. ip = String.Empty; } string exc = includeStackTrace ? LogFormatter.PrintException(exception) : LogFormatter.PrintExceptionWithoutStackTrace(exception); string msg = String.Format("[{0} {1,5}\t{2}\t{3}\t{4}\t{5}]\t{6}\t{7}", LogFormatter.PrintTime(timestamp), //0 Thread.CurrentThread.ManagedThreadId, //1 severity.ToString(), //2 errorCode, //3 caller, //4 ip, //5 message, //6 exc); //7 return(msg); }
/// <summary> /// Async method to validate specific cluster configuration /// </summary> /// <param name="config"></param> /// <returns>Task object of boolean type for this async method </returns> public async Task <bool> ValidateConfiguration(ClusterConfiguration config) { if (config.Globals.LivenessType == GlobalConfiguration.LivenessProviderType.AzureTable) { string clusterId = config.Globals.ClusterId ?? serviceRuntimeWrapper.DeploymentId; string connectionString = config.Globals.DataConnectionString ?? serviceRuntimeWrapper.GetConfigurationSettingValue(DataConnectionConfigurationSettingName); try { var manager = siloInstanceManager ?? await OrleansSiloInstanceManager.GetManager(clusterId, connectionString, AzureStorageClusteringOptions.DEFAULT_TABLE_NAME, loggerFactory); var instances = await manager.DumpSiloInstanceTable(); logger.Debug(instances); } catch (Exception exc) { var error = String.Format("Connecting to the storage table has failed with {0}", LogFormatter.PrintException(exc)); Trace.TraceError(error); logger.Error((int)AzureSiloErrorCode.AzureTable_34, error, exc); return(false); } } return(true); }
/// <summary> /// Generates, compiles, and loads the /// </summary> /// <param name="assemblies"> /// The assemblies to generate code for. /// </param> public Assembly GenerateAndLoadForAssemblies(IEnumerable <Assembly> assemblies) { var assemblyList = assemblies.Where(ShouldGenerateCodeForAssembly).ToList(); try { var timer = Stopwatch.StartNew(); var generated = this.GenerateCode(targetAssembly: null, assemblies: assemblyList); Assembly generatedAssembly; if (generated.Syntax != null) { var emitDebugSymbols = assemblyList.Any(RuntimeVersion.IsAssemblyDebugBuild); generatedAssembly = this.CompileAssembly(generated, "OrleansCodeGen", emitDebugSymbols); } else { generatedAssembly = null; } if (this.logger.IsEnabled(LogLevel.Debug)) { this.logger.Debug( ErrorCode.CodeGenCompilationSucceeded, "Generated code for 1 assembly in {0}ms", timer.ElapsedMilliseconds); } return(generatedAssembly); } catch (Exception exception) { var message = $"Exception generating code for input assemblies {string.Join(",", assemblyList.Select(asm => asm.GetName().FullName))}\nException: {LogFormatter.PrintException(exception)}"; this.logger.Warn(ErrorCode.CodeGenCompilationFailed, message, exception); throw; } }
private string MakeErrorMsg(string what, Exception exc) { var httpStatusCode = HttpStatusCode.Unused; string errorCode = String.Empty; var decoder = store as IRestExceptionDecoder; if (decoder != null) { decoder.DecodeException(exc, out httpStatusCode, out errorCode, true); } GrainReference grainReference = baseGrain.GrainReference; return(string.Format("Error from storage provider during {0} for grain Type={1} Pk={2} Id={3} Error={4}" + Environment.NewLine + " {5}", what, grainTypeName, grainReference.GrainId.ToDetailedString(), grainReference, errorCode, LogFormatter.PrintException(exc))); }
private int CheckLocalHealthCheckParticipants(DateTime now, List <string> complaints) { // Check for execution delays and other local health warning signs. var score = 0; foreach (var participant in _healthCheckParticipants) { try { if (!participant.CheckHealth(_lastHealthCheckTime, out var reason)) { _log.LogWarning("Health check participant {Participant} is reporting that it is unhealthy with complaint: {Reason}", participant?.GetType().ToString(), reason); complaints?.Add($"Health check participant {participant?.GetType().ToString()} is reporting that it is unhealthy with complaint: {reason}"); ++score; } } catch (Exception exception) { _log.LogError(exception, "Error checking health for {Participant}", participant?.GetType().ToString()); complaints?.Add($"Error checking health for participant {participant?.GetType().ToString()}: {LogFormatter.PrintException(exception)}"); ++score; } } _lastHealthCheckTime = now; return(score); }
public int RunMain(string[] args) { ConsoleText.WriteStatus("Orleans-CodeGen - command-line = {0}", Environment.CommandLine); if (args.Length < 1) { PrintUsage(); return(1); } try { var options = new CodeGenOptions(); // STEP 1 : Parse parameters if (args.Length == 1 && args[0].StartsWith("@")) { // Read command line args from file string arg = args[0]; string argsFile = arg.Trim('"').Substring(1).Trim('"'); Console.WriteLine("Orleans-CodeGen - Reading code-gen params from file={0}", argsFile); AssertWellFormed(argsFile, true); args = File.ReadAllLines(argsFile); } int i = 1; foreach (string a in args) { string arg = a.Trim('"').Trim().Trim('"'); if (GrainClientGeneratorFlags.Verbose) { Console.WriteLine("Orleans-CodeGen - arg #{0}={1}", i++, arg); } if (string.IsNullOrEmpty(arg) || string.IsNullOrWhiteSpace(arg)) { continue; } if (arg.StartsWith("/")) { if (arg.StartsWith("/reference:") || arg.StartsWith("/r:")) { // list of references passed from from project file. separator =';' string refstr = arg.Substring(arg.IndexOf(':') + 1); string[] references = refstr.Split(';'); foreach (string rp in references) { AssertWellFormed(rp, true); options.ReferencedAssemblies.Add(rp); } } else if (arg.StartsWith("/in:")) { var infile = arg.Substring(arg.IndexOf(':') + 1); AssertWellFormed(infile); options.InputAssembly = new FileInfo(infile); } else if (arg.StartsWith("/out:")) { var outfile = arg.Substring(arg.IndexOf(':') + 1); AssertWellFormed(outfile, false); options.OutputFileName = outfile; } } else { Console.WriteLine($"Invalid argument: {arg}."); PrintUsage(); return(1); } } // STEP 2 : Validate and calculate unspecified parameters if (options.InputAssembly == null) { Console.WriteLine("ERROR: Orleans-CodeGen - no input file specified."); return(2); } if (String.IsNullOrEmpty(options.OutputFileName)) { Console.WriteLine("ERROR: Orleans-Codegen - no output filename specified"); return(2); } // STEP 3 : Dump useful info for debugging Console.WriteLine($"Orleans-CodeGen - Options {Environment.NewLine}\tInputLib={options.InputAssembly.FullName}{Environment.NewLine}\tOutputFileName={options.OutputFileName}"); if (options.ReferencedAssemblies != null) { Console.WriteLine("Orleans-CodeGen - Using referenced libraries:"); foreach (string assembly in options.ReferencedAssemblies) { Console.WriteLine("\t{0} => {1}", Path.GetFileName(assembly), assembly); } } // STEP 5 : Finally call code generation if (!CreateGrainClientAssembly(options)) { return(-1); } // DONE! return(0); } catch (Exception ex) { Console.WriteLine("-- Code-gen FAILED -- \n{0}", LogFormatter.PrintException(ex)); return(3); } }
public IEventSourcedAggregateRoot <TAggregateRootId> CreateAggregateRoot <TAggregateRootId>(TAggregateRootId aggregateRootId, Type aggregateRootType) { try { var instance = FormatterServices.GetUninitializedObject(aggregateRootType); if (instance is IEventSourcedAggregateRoot <TAggregateRootId> aggregateRoot) { aggregateRoot.Id = aggregateRootId; return(aggregateRoot); } return(null); } catch (Exception e) { _logger.LogError($"Creating aggregate root instance has a unknown exception: {LogFormatter.PrintException(e)}."); return(null); } }
/// <summary> /// Generates and loads code for the specified inputs. /// </summary> /// <param name="inputs">The assemblies to generate code for.</param> public IReadOnlyList <GeneratedAssembly> GenerateAndLoadForAssemblies(params Assembly[] inputs) { if (inputs == null) { throw new ArgumentNullException(nameof(inputs)); } var results = new List <GeneratedAssembly>(); var timer = Stopwatch.StartNew(); var emitDebugSymbols = false; foreach (var input in inputs) { if (!emitDebugSymbols) { emitDebugSymbols |= RuntimeVersion.IsAssemblyDebugBuild(input); } RegisterGeneratedCodeTargets(input); var cached = TryLoadGeneratedAssemblyFromCache(input); if (cached != null) { results.Add(cached); } } var grainAssemblies = inputs.Where(ShouldGenerateCodeForAssembly).ToList(); if (grainAssemblies.Count == 0) { // Already up to date. return(results); } try { // Generate code for newly loaded assemblies. var generatedSyntax = GenerateForAssemblies(grainAssemblies, true); CachedAssembly generatedAssembly; if (generatedSyntax.Syntax != null) { generatedAssembly = CompileAndLoad(generatedSyntax, emitDebugSymbols); if (generatedAssembly != null) { results.Add(generatedAssembly); } } else { generatedAssembly = new CachedAssembly { Loaded = true }; } foreach (var assembly in generatedSyntax.SourceAssemblies) { CompiledAssemblies.AddOrUpdate( assembly.GetName().FullName, generatedAssembly, (_, __) => generatedAssembly); } if (Logger.IsVerbose2) { Logger.Verbose2( ErrorCode.CodeGenCompilationSucceeded, "Generated code for {0} assemblies in {1}ms", generatedSyntax.SourceAssemblies.Count, timer.ElapsedMilliseconds); } return(results); } catch (Exception exception) { var assemblyNames = string.Join("\n", grainAssemblies.Select(_ => _.GetName().FullName)); var message = $"Exception generating code for input assemblies:\n{assemblyNames}\nException: {LogFormatter.PrintException(exception)}"; Logger.Warn(ErrorCode.CodeGenCompilationFailed, message, exception); throw; } }
public static int Main(string[] args) { Console.WriteLine("Orleans-CodeGen - command-line = {0}", Environment.CommandLine); if (args.Length < 1) { PrintUsage(); return(1); } try { var options = new CodeGenOptions(); // STEP 1 : Parse parameters if (args.Length == 1 && args[0].StartsWith("@")) { // Read command line args from file string arg = args[0]; string argsFile = arg.Trim('"').Substring(1).Trim('"'); Console.WriteLine("Orleans-CodeGen - Reading code-gen params from file={0}", argsFile); AssertWellFormed(argsFile); args = File.ReadAllLines(argsFile); } foreach (string a in args) { string arg = a.Trim('"').Trim().Trim('"'); if (string.IsNullOrEmpty(arg) || string.IsNullOrWhiteSpace(arg)) { continue; } if (arg.StartsWith("/")) { if (arg.StartsWith("/reference:") || arg.StartsWith("/r:")) { // list of references passed from from project file. separator =';' string refstr = arg.Substring(arg.IndexOf(':') + 1); string[] references = refstr.Split(';'); foreach (string rp in references) { AssertWellFormed(rp); options.ReferencedAssemblies.Add(rp); } } else if (arg.StartsWith("/in:")) { var infile = arg.Substring(arg.IndexOf(':') + 1); AssertWellFormed(infile); options.InputAssembly = new FileInfo(infile); } else if (arg.StartsWith("/out:")) { var outfile = arg.Substring(arg.IndexOf(':') + 1); AssertWellFormed(outfile); options.OutputFileName = outfile; } } else { Console.WriteLine($"Invalid argument: {arg}."); PrintUsage(); return(1); } } // STEP 2 : Validate and calculate unspecified parameters if (options.InputAssembly == null) { Console.WriteLine("ERROR: Orleans-CodeGen - no input file specified."); return(2); } if (String.IsNullOrEmpty(options.OutputFileName)) { Console.WriteLine("ERROR: Orleans-Codegen - no output filename specified"); return(2); } // STEP 3 : Dump useful info for debugging Console.WriteLine($"Orleans-CodeGen - Options {Environment.NewLine}\tInputLib={options.InputAssembly.FullName}{Environment.NewLine}\tOutputFileName={options.OutputFileName}"); bool referencesOrleans = options.InputAssembly.Name.Equals(CodeGenerator.OrleansAssemblyFileName); foreach (string assembly in options.ReferencedAssemblies) { var fileName = Path.GetFileName(assembly); Console.WriteLine("\t{0} => {1}", fileName, assembly); if (fileName != null && fileName.Equals(CodeGenerator.OrleansAssemblyFileName)) { referencesOrleans = true; } } // STEP 5 : Finally call code generation if (referencesOrleans) { if (!CodeGenerator.GenerateCode(options)) { Console.WriteLine("WARNING: Orleans-CodeGen - the input assembly contained no types which required code generation."); } } else { Console.WriteLine("ERROR: Orleans-CodeGen - the input assembly does not reference Orleans and therefore code can not be generated."); return(-2); } // DONE! return(0); } catch (Exception ex) { Console.WriteLine("-- Code Generation FAILED -- \n{0}", LogFormatter.PrintException(ex)); return(3); } }
/// <summary> /// Initialize this Orleans silo for execution with the specified Azure clusterId /// </summary> /// <param name="config">If null, Config data will be read from silo config file as normal, otherwise use the specified config data.</param> /// <param name="clusterId">Azure ClusterId this silo is running under</param> /// <param name="connectionString">Azure DataConnectionString. If null, defaults to the DataConnectionString setting from the Azure configuration for this role.</param> /// <returns><c>true</c> if the silo startup was successful</returns> internal bool Start(ClusterConfiguration config, string clusterId, string connectionString) { if (config != null && clusterId != null) { throw new ArgumentException("Cannot use config and clusterId on the same time"); } // Program ident Trace.TraceInformation("Starting {0} v{1}", this.GetType().FullName, RuntimeVersion.Current); // Read endpoint info for this instance from Azure config string instanceName = serviceRuntimeWrapper.InstanceName; // Configure this Orleans silo instance if (config == null) { host = new SiloHost(instanceName); host.LoadOrleansConfig(); // Load config from file + Initializes logger configurations } else { host = new SiloHost(instanceName, config); // Use supplied config data + Initializes logger configurations } IPEndPoint myEndpoint = serviceRuntimeWrapper.GetIPEndpoint(SiloEndpointConfigurationKeyName); IPEndPoint proxyEndpoint = serviceRuntimeWrapper.GetIPEndpoint(ProxyEndpointConfigurationKeyName); host.SetSiloType(Silo.SiloType.Secondary); int generation = SiloAddress.AllocateNewGeneration(); // Bootstrap this Orleans silo instance // If clusterId was not direclty provided, take the value in the config. If it is not // in the config too, just take the ClusterId from Azure if (clusterId == null) { clusterId = string.IsNullOrWhiteSpace(host.Config.Globals.ClusterId) ? serviceRuntimeWrapper.DeploymentId : host.Config.Globals.ClusterId; } myEntry = new SiloInstanceTableEntry { DeploymentId = clusterId, Address = myEndpoint.Address.ToString(), Port = myEndpoint.Port.ToString(CultureInfo.InvariantCulture), Generation = generation.ToString(CultureInfo.InvariantCulture), HostName = host.Config.GetOrCreateNodeConfigurationForSilo(host.Name).DNSHostName, ProxyPort = (proxyEndpoint != null ? proxyEndpoint.Port : 0).ToString(CultureInfo.InvariantCulture), RoleName = serviceRuntimeWrapper.RoleName, SiloName = instanceName, UpdateZone = serviceRuntimeWrapper.UpdateDomain.ToString(CultureInfo.InvariantCulture), FaultZone = serviceRuntimeWrapper.FaultDomain.ToString(CultureInfo.InvariantCulture), StartTime = LogFormatter.PrintDate(DateTime.UtcNow), PartitionKey = clusterId, RowKey = myEndpoint.Address + "-" + myEndpoint.Port + "-" + generation }; if (connectionString == null) { connectionString = serviceRuntimeWrapper.GetConfigurationSettingValue(DataConnectionConfigurationSettingName); } try { siloInstanceManager = OrleansSiloInstanceManager.GetManager( clusterId, connectionString, AzureStorageClusteringOptions.DEFAULT_TABLE_NAME, this.loggerFactory).WithTimeout(AzureTableDefaultPolicies.TableCreationTimeout).Result; } catch (Exception exc) { var error = String.Format("Failed to create OrleansSiloInstanceManager. This means CreateTableIfNotExist for silo instance table has failed with {0}", LogFormatter.PrintException(exc)); Trace.TraceError(error); logger.Error((int)AzureSiloErrorCode.AzureTable_34, error, exc); throw new OrleansException(error, exc); } // Always use Azure table for membership when running silo in Azure host.SetSiloLivenessType(GlobalConfiguration.LivenessProviderType.AzureTable); if (host.Config.Globals.ReminderServiceType == GlobalConfiguration.ReminderServiceProviderType.NotSpecified || host.Config.Globals.ReminderServiceType == GlobalConfiguration.ReminderServiceProviderType.ReminderTableGrain) { host.SetReminderServiceType(GlobalConfiguration.ReminderServiceProviderType.AzureTable); } host.SetExpectedClusterSize(serviceRuntimeWrapper.RoleInstanceCount); siloInstanceManager.RegisterSiloInstance(myEntry); // Initialize this Orleans silo instance host.SetDeploymentId(clusterId, connectionString); host.SetSiloEndpoint(myEndpoint, generation); host.SetProxyEndpoint(proxyEndpoint); host.ConfigureSiloHostDelegate = ConfigureSiloHostDelegate; host.InitializeOrleansSilo(); return(StartSilo()); }
public async Task CheckpointAsync( IEventSourcedAggregateRoot aggregateRoot, CancellationToken token = default) { var aggregateRootId = aggregateRoot.Id; var aggregateRootType = aggregateRoot.GetType().FullName; var aggregateGeneration = aggregateRoot.Generation; var aggregateVersion = aggregateRoot.Version; var metrics = await _eventStateBackend.StatMetricsAsync(aggregateRootId, aggregateGeneration, token); if (metrics.TriggerCheckpoint(_options)) { var nextGeneration = ++aggregateRoot.Generation; var checkpoint = new AggregateRootCheckpoint <IEventSourcedAggregateRoot>(aggregateRoot.Id, aggregateRoot.GetType(), nextGeneration, aggregateRoot.Version, aggregateRoot); var message = $"id: {aggregateRootId}, Type: {aggregateRootType}, Generation: {nextGeneration}, Version: {aggregateVersion}, UnCheckpointedBytes: {metrics.UnCheckpointedBytes} >= {_options.UnCheckpointedBytes}, UnCheckpointedCount: {metrics.UnCheckpointedCount} >= {_options.UnCheckpointedCount}"; try { await _checkpointStateBackend.AppendAsync(checkpoint, token); } catch (Exception e) { _logger.LogInformation($"Checkpointing the aggregate root, {message} has a unknown exception: {LogFormatter.PrintException(e)}."); return; } _logger.LogInformation($"Checkpointed the aggregate root, {message}."); } else { _logger.LogInformation($"No triggering checkpoint for the aggregate root, id: {aggregateRootId}, Type: {aggregateRootType}, Generation: {aggregateGeneration}, Version: {aggregateVersion}, UnCheckpointedBytes: {metrics.UnCheckpointedBytes} < {_options.UnCheckpointedBytes}, UnCheckpointedCount: {metrics.UnCheckpointedCount} < {_options.UnCheckpointedCount}."); } }
private async Task ProcessUnKnownExceptionAsync(IDomainCommand command, Exception exception, CancellationToken token) { _logger.LogError($"Handling domain command[Id: {command.Id}, Type: {command.GetType().FullName}, application command[{command.ApplicationCommandId}, {command.ApplicationCommandType}, reply scheme: {command.ApplicationCommandReplyScheme}], aggregate root[{command.AggregateRootId},{command.AggregateRootType.FullName}], has a unknown exceptionException: {LogFormatter.PrintException(exception)}."); var canReturnOnDomainCommandHandled = command.ApplicationCommandReplyScheme == ApplicationCommandReplySchemes.OnDomainCommandHandled; if (!canReturnOnDomainCommandHandled) { return; } var domainExceptionMessage = new DomainExceptionMessage() { Message = exception.Message }; domainExceptionMessage.FillFrom(command); await PublishDomainExceptionAsync(domainExceptionMessage, token); }
private async Task ProcessDomainExceptionAsync(IDomainCommand command, DomainException domainException, CancellationToken token) { var commandId = command.Id; var commandType = command.GetType().FullName; var canReturnOnDomainCommandHandled = command.ApplicationCommandReplyScheme == ApplicationCommandReplySchemes.OnDomainCommandHandled; _logger.LogError($"Handling domain command has a domain exception, Id: {commandId}, Type: {commandType}, Exception: {LogFormatter.PrintException(domainException)}."); if (!canReturnOnDomainCommandHandled) { return; } var domainExceptionMessage = new DomainExceptionMessage() { Message = domainException.Message, Code = domainException.Code }; domainExceptionMessage.FillFrom(command); await PublishDomainExceptionAsync(domainExceptionMessage, token); }
private string MakeErrorMsg(string what, Exception exc) { HttpStatusCode httpStatusCode; string errorCode = string.Empty; var decoder = store as IRestExceptionDecoder; decoder?.DecodeException(exc, out httpStatusCode, out errorCode, true); return(string.Format("Error from storage provider during {0} for grain Type={1} Pk={2} Id={3} Error={4}" + Environment.NewLine + " {5}", what, name, grainRef.GrainId.ToDetailedString(), grainRef, errorCode, LogFormatter.PrintException(exc))); }
/// <summary> /// Report an error during silo startup. /// </summary> /// <remarks> /// Information on the silo startup issue will be logged to any attached Loggers, /// then a timestamped StartupError text file will be written to /// the current working directory (if possible). /// </remarks> /// <param name="exc">Exception which caused the silo startup issue.</param> public void ReportStartupError(Exception exc) { if (string.IsNullOrWhiteSpace(Name)) { Name = "Silo"; } var errMsg = "ERROR starting Orleans silo name=" + Name + " Exception=" + LogFormatter.PrintException(exc); if (logger != null) { logger.Error(ErrorCode.Runtime_Error_100105, errMsg, exc); } // Dump Startup error to a log file var now = DateTime.UtcNow; var dateString = now.ToString(dateFormat, CultureInfo.InvariantCulture); var startupLog = Name + "-StartupError-" + dateString + ".txt"; try { File.AppendAllText(startupLog, dateString + "Z" + Environment.NewLine + errMsg); } catch (Exception exc2) { if (logger != null) { logger.Error(ErrorCode.Runtime_Error_100106, "Error writing log file " + startupLog, exc2); } } }
/// <summary> /// Ensures that code generation has been run for the provided assembly. /// </summary> /// <param name="input"> /// The assembly to generate code for. /// </param> public GeneratedAssembly GenerateAndLoadForAssembly(Assembly input) { try { RegisterGeneratedCodeTargets(input); if (!ShouldGenerateCodeForAssembly(input)) { return(TryLoadGeneratedAssemblyFromCache(input)); } var timer = Stopwatch.StartNew(); var generated = GenerateForAssemblies(new List <Assembly> { input }, true); CachedAssembly generatedAssembly; if (generated.Syntax != null) { var emitDebugSymbols = RuntimeVersion.IsAssemblyDebugBuild(input); generatedAssembly = CompileAndLoad(generated, emitDebugSymbols); } else { generatedAssembly = new CachedAssembly { Loaded = true }; } foreach (var assembly in generated.SourceAssemblies) { CompiledAssemblies.AddOrUpdate( assembly.GetName().FullName, generatedAssembly, (_, __) => generatedAssembly); } if (Logger.IsVerbose2) { Logger.Verbose2( ErrorCode.CodeGenCompilationSucceeded, "Generated code for 1 assembly in {0}ms", timer.ElapsedMilliseconds); } return(generatedAssembly); } catch (Exception exception) { var message = $"Exception generating code for input assembly {input.GetName().FullName}\nException: {LogFormatter.PrintException(exception)}"; Logger.Warn(ErrorCode.CodeGenCompilationFailed, message, exception); throw; } }
private static void InitializeImpl_FromFile(FileInfo configFile) { if (GrainClient.IsInitialized) { Trace.TraceInformation("Connection to Orleans gateway silo already initialized."); return; } ClientConfiguration config; try { if (configFile == null) { Trace.TraceInformation("Looking for standard Orleans client config file"); config = ClientConfiguration.StandardLoad(); } else { var configFileLocation = configFile.FullName; Trace.TraceInformation("Loading Orleans client config file {0}", configFileLocation); config = ClientConfiguration.LoadFromFile(configFileLocation); } } catch (Exception ex) { var msg = String.Format("Error loading Orleans client configuration file {0} {1} -- unable to continue. {2}", configFile, ex.Message, LogFormatter.PrintException(ex)); Trace.TraceError(msg); throw new AggregateException(msg, ex); } Trace.TraceInformation("Overriding Orleans client config from Azure runtime environment."); try { config.DeploymentId = GetDeploymentId(); config.DataConnectionString = GetDataConnectionString(); config.GatewayProvider = ClientConfiguration.GatewayProviderType.AzureTable; } catch (Exception ex) { var msg = string.Format("ERROR: No AzureClient role setting value '{0}' specified for this role -- unable to continue", AzureConstants.DataConnectionConfigurationSettingName); Trace.TraceError(msg); throw new AggregateException(msg, ex); } InitializeImpl_FromConfig(config); }
public async Task <GrainStateRecord> Read(string partitionKey, string rowKey) { if (logger.IsEnabled(LogLevel.Trace)) { logger.Trace((int)AzureProviderErrorCode.AzureTableProvider_Storage_Reading, "Reading: PartitionKey={0} RowKey={1} from Table={2}", partitionKey, rowKey, TableName); } try { Tuple <DynamicTableEntity, string> data = await tableManager.ReadSingleTableEntryAsync(partitionKey, rowKey).ConfigureAwait(false); if (data == null || data.Item1 == null) { if (logger.IsEnabled(LogLevel.Trace)) { logger.Trace((int)AzureProviderErrorCode.AzureTableProvider_DataNotFound, "DataNotFound reading: PartitionKey={0} RowKey={1} from Table={2}", partitionKey, rowKey, TableName); } return(null); } DynamicTableEntity stateEntity = data.Item1; var record = new GrainStateRecord { Entity = stateEntity, ETag = data.Item2 }; if (logger.IsEnabled(LogLevel.Trace)) { logger.Trace((int)AzureProviderErrorCode.AzureTableProvider_Storage_DataRead, "Read: PartitionKey={0} RowKey={1} from Table={2} with ETag={3}", stateEntity.PartitionKey, stateEntity.RowKey, TableName, record.ETag); } return(record); } catch (Exception exc) { if (AzureStorageUtils.TableStorageDataNotFound(exc)) { if (logger.IsEnabled(LogLevel.Trace)) { logger.Trace((int)AzureProviderErrorCode.AzureTableProvider_DataNotFound, "DataNotFound reading (exception): PartitionKey={0} RowKey={1} from Table={2} Exception={3}", partitionKey, rowKey, TableName, LogFormatter.PrintException(exc)); } return(null); // No data } throw; } }
private static void InitializeImpl_FromConfig(ClientConfiguration config) { if (GrainClient.IsInitialized) { Trace.TraceInformation("Connection to Orleans gateway silo already initialized."); return; } //// Find endpoint info for the gateway to this Orleans silo cluster //Trace.WriteLine("Searching for Orleans gateway silo via Orleans instance table..."); var deploymentId = config.DeploymentId; var connectionString = config.DataConnectionString; if (String.IsNullOrEmpty(deploymentId)) { throw new ArgumentException("Cannot connect to Azure silos with null deploymentId", "config.DeploymentId"); } if (String.IsNullOrEmpty(connectionString)) { throw new ArgumentException("Cannot connect to Azure silos with null connectionString", "config.DataConnectionString"); } bool initSucceeded = false; Exception lastException = null; for (int i = 0; i < MaxRetries; i++) { try { //parse through ConfigureLoggingDelegate to GrainClient GrainClient.ConfigureLoggingDelegate = ConfigureLoggingDelegate; // Initialize will throw if cannot find Gateways GrainClient.Initialize(config); initSucceeded = true; break; } catch (Exception exc) { lastException = exc; Trace.TraceError("Client.Initialize failed with exc -- {0}. Will try again", exc.Message); } // Pause to let Primary silo start up and register Trace.TraceInformation("Pausing {0} awaiting silo and gateways registration for Deployment={1}", StartupRetryPause, deploymentId); Thread.Sleep(StartupRetryPause); } if (initSucceeded) { return; } OrleansException err; err = lastException != null ? new OrleansException(String.Format("Could not Initialize Client for DeploymentId={0}. Last exception={1}", deploymentId, lastException.Message), lastException) : new OrleansException(String.Format("Could not Initialize Client for DeploymentId={0}.", deploymentId)); Trace.TraceError("Error starting Orleans Azure client application -- {0} -- bailing. {1}", err.Message, LogFormatter.PrintException(err)); throw err; }
public int RunMain(string[] args) { ConsoleText.WriteStatus("Orleans-CodeGen - command-line = {0}", Environment.CommandLine); if (args.Length < 1) { Console.WriteLine( "Usage: ClientGenerator.exe <grain interface dll path> [<client dll path>] [<key file>] [<referenced assemblies>]"); Console.WriteLine( " ClientGenerator.exe /server <grain dll path> [<factory dll path>] [<key file>] [<referenced assemblies>]"); return(1); } try { var options = new CodeGenOptions(); // STEP 1 : Parse parameters if (args.Length == 1 && args[0].StartsWith("@")) { // Read command line args from file string arg = args[0]; string argsFile = arg.Trim('"').Substring(1).Trim('"'); Console.WriteLine("Orleans-CodeGen - Reading code-gen params from file={0}", argsFile); AssertWellFormed(argsFile, true); args = File.ReadAllLines(argsFile); } int i = 1; foreach (string a in args) { string arg = a.Trim('"').Trim().Trim('"'); if (GrainClientGeneratorFlags.Verbose) { Console.WriteLine("Orleans-CodeGen - arg #{0}={1}", i++, arg); } if (string.IsNullOrEmpty(arg) || string.IsNullOrWhiteSpace(arg)) { continue; } if (arg.StartsWith("/")) { if (arg.StartsWith("/reference:") || arg.StartsWith("/r:")) { // list of references passed from from project file. separator =';' string refstr = arg.Substring(arg.IndexOf(':') + 1); string[] references = refstr.Split(';'); foreach (string rp in references) { AssertWellFormed(rp, true); options.ReferencedAssemblies.Add(rp); } } else if (arg.StartsWith("/in:")) { var infile = arg.Substring(arg.IndexOf(':') + 1); AssertWellFormed(infile); options.InputLib = new FileInfo(infile); } else if (arg.StartsWith("/bootstrap") || arg.StartsWith("/boot")) { // special case for building circular dependecy in preprocessing: // Do not build the input assembly, assume that some other build step options.CodeGenFile = Path.GetFullPath(CodeGenFileRelativePathCSharp); if (GrainClientGeneratorFlags.Verbose) { Console.WriteLine( "Orleans-CodeGen - Set CodeGenFile={0} from bootstrap", options.CodeGenFile); } } else if (arg.StartsWith("/sources:") || arg.StartsWith("/src:")) { var sourcesStr = arg.Substring(arg.IndexOf(':') + 1); string[] sources = sourcesStr.Split(';'); foreach (var source in sources) { HandleSourceFile(source, options); } } } else { HandleSourceFile(arg, options); } } if (options.InvalidLanguage) { ConsoleText.WriteLine( "ERROR: Compile-time code generation is supported for C# only. " + "Remove code generation from your project in order to use run-time code generation."); return(2); } // STEP 2 : Validate and calculate unspecified parameters if (options.InputLib == null) { Console.WriteLine("ERROR: Orleans-CodeGen - no input file specified."); return(2); } #if !NETSTANDARD if (string.IsNullOrEmpty(options.CodeGenFile)) { Console.WriteLine( "ERROR: No codegen file. Add a file '{0}' to your project", Path.Combine("Properties", "orleans.codegen.cs")); return(2); } #endif options.SourcesDir = Path.Combine(options.InputLib.DirectoryName, "Generated"); // STEP 3 : Dump useful info for debugging Console.WriteLine( "Orleans-CodeGen - Options " + Environment.NewLine + "\tInputLib={0} " + Environment.NewLine + "\tCodeGenFile={1}", options.InputLib.FullName, options.CodeGenFile); if (options.ReferencedAssemblies != null) { Console.WriteLine("Orleans-CodeGen - Using referenced libraries:"); foreach (string assembly in options.ReferencedAssemblies) { Console.WriteLine("\t{0} => {1}", Path.GetFileName(assembly), assembly); } } // STEP 5 : Finally call code generation if (!CreateGrainClientAssembly(options)) { return(-1); } // DONE! return(0); } catch (Exception ex) { Console.WriteLine("-- Code-gen FAILED -- \n{0}", LogFormatter.PrintException(ex)); return(3); } }
private string MakeErrorMsg(string what, Exception exc) { string errorCode = string.Empty; var decoder = store as IRestExceptionDecoder; decoder?.DecodeException(exc, out _, out errorCode, true); return(string.Format("Error from storage provider {0} during {1} for grain Type={2} Pk={3} Id={4} Error={5}" + Environment.NewLine + " {6}", $"{this.store.GetType().Name}.{this.name}", what, name, grainRef.GrainId.ToString(), grainRef, errorCode, LogFormatter.PrintException(exc))); }