public async Task Invoke(HttpContext context) { if (!_hasProvider) { await _next.Invoke(context); return; } try { // Add Telemetry. using (var activity = _activitySource?.StartActivity("Create Arc4u Principal", ActivityKind.Producer)) { var clientSecret = GetClientSecretIfExist(context, _option.SecretKey); bool basicAuthenticationSecret = !String.IsNullOrWhiteSpace(clientSecret); bool certificateAuthenticationSecret = false; // Check for a secret key encrypted. if (_hasCertificate && !basicAuthenticationSecret) { clientSecret = GetClientSecretIfExist(context, _option.Certificate.SecretKey); certificateAuthenticationSecret = !String.IsNullOrWhiteSpace(clientSecret); } if (!String.IsNullOrWhiteSpace(clientSecret)) { CredentialsResult credential = null; if (basicAuthenticationSecret) { credential = GetCredential(clientSecret); } if (certificateAuthenticationSecret) { credential = GetCertificateCredential(clientSecret); } if (null != credential) { // Get an Access Token. var tokenInfo = await _provider.GetTokenAsync(_option.Settings, credential); // Replace the Basic Authorization by the access token in the header. var authorization = new AuthenticationHeaderValue("Bearer", tokenInfo.AccessToken).ToString(); context.Request.Headers.Remove("Authorization"); context.Request.Headers.Add("Authorization", authorization); } } } } catch (Exception ex) { _logger.Technical().Exception(ex).Log(); } await _next(context); }
public async Task Invoke(HttpContext context) { if (context.User.Identity.IsAuthenticated && context.User.Identity.AuthenticationType.Equals(_options.OpenIdSettings.Values[TokenKeys.AuthenticationTypeKey], StringComparison.InvariantCultureIgnoreCase)) { if (context.User is AppPrincipal principal) { context.Request?.Headers?.Add("activityid", principal?.ActivityID.ToString() ?? Guid.NewGuid().ToString()); if (null != principal?.Profile?.CurrentCulture) { context.Request?.Headers?.Add("culture", principal.Profile.CurrentCulture.TwoLetterISOLanguageName); } } IContainerResolve container = (IContainerResolve)context.RequestServices.GetService(typeof(IContainerResolve)); // Not thread safe => can call activity source factory more than one but factory implementation is thread safe => so few calls on the start of the service is a possibility. if (!hasAlreadyTriedToResolve) { hasAlreadyTriedToResolve = true; _activitySource = container.Resolve <IActivitySourceFactory>()?.GetArc4u(); } using (var activity = _activitySource?.StartActivity("Inject bearer token in header", ActivityKind.Producer)) { ITokenProvider provider = container.Resolve <ITokenProvider>(_options.OpenIdSettings.Values[TokenKeys.ProviderIdKey]); var tokenInfo = await provider.GetTokenAsync(_options.OpenIdSettings, context.User.Identity); var authorization = new AuthenticationHeaderValue("Bearer", tokenInfo.AccessToken).ToString(); context.Request.Headers.Remove("Authorization"); context.Request.Headers.Add("Authorization", authorization); } } await _next.Invoke(context); }
public async Task CompleteAsync() { var messages = QueueMessages; var pubSubEvents = PubSubEvents; if (messages.Count > 0 || pubSubEvents.Count > 0) { using (var activity = _activitySource?.StartActivity("Send to KubeMQ")) { if (messages.Count > 0) { activity?.AddTag("QueueMessages", messages.Count); _logger.Technical().System($"{messages.Count} messages will be sent to queues.").Log(); _queueMessageSender.SendBatch(messages); } if (pubSubEvents.Count > 0) { activity?.AddTag("PubSubMessages", pubSubEvents.Count); _logger.Technical().System($"{pubSubEvents.Count} event(s) will be sent to publishers.").Log(); await _publisher.PublishBatchAsync(pubSubEvents); } // Clear because messages have been processed. _messagesToPublish.Clear(); } } }
public async Task Invoke(HttpContext context) { if (!_hasProvider) { await _next(context); return; } try { TokenInfo tokenInfo; if (context.Request.Headers.ContainsKey("Authorization")) { if (context.Request.Headers.TryGetValue("Authorization", out var authzValue) && authzValue.Any(value => value.Contains("Basic"))) { // Add Telemetry. using (var activity = _activitySource?.StartActivity("BasicAuthentication", ActivityKind.Producer)) { var cacheKey = BuildKey(authzValue); tokenInfo = _tokenCache?.Get <TokenInfo>(cacheKey); if (null == tokenInfo || tokenInfo.ExpiresOnUtc < DateTime.UtcNow.AddMinutes(1)) { var credential = GetCredential(authzValue); if (null != credential && credential.CredentialsEntered) { // Get an Access Token. tokenInfo = await _provider.GetTokenAsync(_option.Settings, credential); _tokenCache?.Put(cacheKey, tokenInfo); } } if (null != tokenInfo) { // Replace the Basic Authorization by the access token in the header. var authorization = new AuthenticationHeaderValue("Bearer", tokenInfo.AccessToken).ToString(); context.Request.Headers.Remove("Authorization"); context.Request.Headers.Add("Authorization", authorization); } } } } } catch (Exception ex) { _logger.Technical().Exception(ex).Log(); } await _next(context); }
public void Publish <TEvent>(TEvent @event, Dictionary <string, string> tags = null) where TEvent : notnull { using (var activity = _activitySource?.StartActivity("Send PubSub event to KubeMQ", ActivityKind.Producer)) { if (typeof(TEvent) is IEnumerable) { throw new ArgumentException("Collection are not accepted!"); } var definition = GetDefiniton(typeof(TEvent)); var channel = CreateChannel(definition); var serializer = GetSerializer(definition); string activityId = _applicationContext?.Principal?.ActivityID.ToString() ?? Guid.NewGuid().ToString(); KubeMQEvent message = null; using (var serializerActivity = _activitySource?.StartActivity("Serialize.", ActivityKind.Producer)) message = new KubeMQEvent(null, string.Empty, serializer.Serialize(@event).ToArray(), BuildTags(typeof(TEvent), tags, activityId)); using (var sendActivity = _activitySource?.StartActivity("Send to KubeMQ", ActivityKind.Producer)) channel.SendEvent(message); } }
public void Send <TMessage>(TMessage message, Dictionary <string, string> tags = null, uint?sendAfterSeconds = null, uint?expireAfterSeconds = null) where TMessage : notnull { using (var activity = _activitySource?.StartActivity("Send message to KubeMQ", ActivityKind.Producer)) { activity?.AddTag("Delay message [s]", sendAfterSeconds); activity?.AddTag("Expire message after [s]", expireAfterSeconds); if (message is IEnumerable) { throw new ArgumentException("Collection are not accepted!"); } var messageType = typeof(TMessage); var definition = GetDefiniton(messageType); var policy = definition.RetryPolicy(Policy.Handle <Exception>()); QueueStream queue = null; policy.Execute(() => queue = _queueStreamManager.Get(definition)); if (null == queue) { throw new NullReferenceException($"No queue was created for Address: {definition.Address} and Identitfier {definition.Identifier}"); } var serializer = GetSerializer(definition); string activityId = _applicationContext?.Principal?.ActivityID.ToString() ?? Guid.NewGuid().ToString(); Message _message = null; using (var serializerActivity = _activitySource?.StartActivity("Serialize.", ActivityKind.Producer)) _message = new Message(definition.Namespace, serializer.Serialize(message), String.Empty, Guid.NewGuid().ToString(), BuildTags(messageType, tags, activityId)) { Policy = BuildPolicy(definition, sendAfterSeconds, expireAfterSeconds) }; using (var sendActivity = _activitySource?.StartActivity("Send to KubeMQ", ActivityKind.Producer)) queue.Send(new SendRequest(new List <Message>(1) { _message })); } }
internal static object Run() { System.Console.WriteLine("Hello World!"); using var openTelemetry = Sdk.CreateTracerProviderBuilder() .AddHttpClientInstrumentation() .SetResource(Resources.CreateServiceResource("http-service-example")) .AddSource("http-client-test") .AddConsoleExporter() .Build(); var source = new ActivitySource("http-client-test"); using (var parent = source.StartActivity("incoming request", ActivityKind.Server)) { using var client = new HttpClient(); client.GetStringAsync("http://bing.com").GetAwaiter().GetResult(); } System.Console.ReadLine(); return(null); }
public void GeneratePartAEnvelope_Activity_WithResource() { using ActivitySource activitySource = new ActivitySource(ActivitySourceName); using var activity = activitySource.StartActivity( ActivityName, ActivityKind.Client, parentContext: default, startTime: DateTime.UtcNow); var resource = CreateTestResource(serviceName: "my-service", serviceInstance: "my-instance"); var monitorTags = AzureMonitorConverter.EnumerateActivityTags(activity); var telemetryItem = TelemetryPartA.GetTelemetryItem(activity, ref monitorTags, resource, null); Assert.Equal("RemoteDependency", telemetryItem.Name); Assert.Equal(TelemetryPartA.FormatUtcTimestamp(activity.StartTimeUtc), telemetryItem.Time); Assert.Equal("my-service", telemetryItem.Tags[ContextTagKeys.AiCloudRole.ToString()]); Assert.Equal("my-instance", telemetryItem.Tags[ContextTagKeys.AiCloudRoleInstance.ToString()]); Assert.Equal(activity.TraceId.ToHexString(), telemetryItem.Tags[ContextTagKeys.AiOperationId.ToString()]); Assert.Equal(SdkVersionUtils.SdkVersion, telemetryItem.Tags[ContextTagKeys.AiInternalSdkVersion.ToString()]); Assert.Throws <KeyNotFoundException>(() => telemetryItem.Tags[ContextTagKeys.AiOperationParentId.ToString()]); }
public void SetErrorStatusOnExceptionDefault() { using var activitySource = new ActivitySource(ActivitySourceName); using var tracerProvider = OpenTelemetrySdk.CreateTracerProviderBuilder() .AddSource(ActivitySourceName) .SetSampler(new AlwaysOnSampler()) .Build(); Activity activity = null; try { using (activity = activitySource.StartActivity("Activity")) { throw new Exception("Oops!"); } } catch (Exception) { } Assert.Equal(StatusCode.Unset, activity.GetStatus().StatusCode); }
public void StackdriverExporter_TraceClientThrows_ExportResultFailure() { Exception exception = null; ExportResult result = ExportResult.Success; const string ActivitySourceName = "stackdriver.test"; var source = new ActivitySource(ActivitySourceName); var traceClientMock = new Mock <TraceServiceClient>(MockBehavior.Strict); traceClientMock.Setup(x => x.BatchWriteSpans(It.IsAny <BatchWriteSpansRequest>(), It.IsAny <CallSettings>())) .Throws(new RpcException(Status.DefaultCancelled)) .Verifiable($"{nameof(TraceServiceClient.BatchWriteSpans)} was never called"); var activityExporter = new StackdriverTraceExporter("test", traceClientMock.Object); var testExporter = new TestExporter <Activity>(RunTest); var processor = new BatchActivityExportProcessor(testExporter); for (int i = 0; i < 10; i++) { using Activity activity = source.StartActivity("Test Activity"); processor.OnEnd(activity); } processor.Shutdown(); void RunTest(Batch <Activity> batch) { exception = Record.Exception(() => { result = activityExporter.Export(batch); }); } Assert.Null(exception); Assert.StrictEqual(ExportResult.Failure, result); traceClientMock.VerifyAll(); }
private static Activity OnFunctionStart(ILambdaContext context = null) { Activity activity = null; var parentContext = AWSLambdaUtils.GetParentContext(); if (parentContext != default) { var activityName = AWSLambdaUtils.GetFunctionName(context); activity = AWSLambdaActivitySource.StartActivity(activityName, ActivityKind.Server, parentContext); if (activity != null && context != null) { if (activity.IsAllDataRequested) { if (context.AwsRequestId != null) { activity.SetTag(AWSLambdaSemanticConventions.AttributeFaasExecution, context.AwsRequestId); } var functionArn = context.InvokedFunctionArn; if (functionArn != null) { activity.SetTag(AWSLambdaSemanticConventions.AttributeFaasID, functionArn); var accountId = AWSLambdaUtils.GetAccountId(functionArn); if (accountId != null) { activity.SetTag(AWSLambdaSemanticConventions.AttributeCloudAccountID, accountId); } } } } } return(activity); }
public void ExportResultIsSuccess() { #if NETCOREAPP3_1 // Adding the OtlpExporter creates a GrpcChannel. // This switch must be set before creating a GrpcChannel/HttpClient when calling an insecure gRPC service. // See: https://docs.microsoft.com/aspnet/core/grpc/troubleshoot#call-insecure-grpc-services-with-net-core-client AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true); #endif var exporterOptions = new OtlpExporterOptions { #if NETCOREAPP3_1 || NET5_0 Endpoint = new System.Uri($"http://{CollectorEndpoint}"), #else Endpoint = CollectorEndpoint, #endif }; var otlpExporter = new OtlpExporter(exporterOptions); var delegatingExporter = new DelegatingTestExporter <Activity>(otlpExporter); var exportActivityProcessor = new SimpleActivityExportProcessor(delegatingExporter); var activitySourceName = "otlp.collector.test"; var builder = Sdk.CreateTracerProviderBuilder() .AddSource(activitySourceName) .AddProcessor(exportActivityProcessor); using var tracerProvider = builder.Build(); var source = new ActivitySource(activitySourceName); var activity = source.StartActivity("Test Activity"); activity?.Stop(); Assert.Single(delegatingExporter.ExportResults); Assert.Equal(ExportResult.Success, delegatingExporter.ExportResults[0]); }
public async Task Run() { using var act = source.StartActivity(GetType().Name); act?.SetParentId(Tracer.CurrentSpan.Context.TraceId, Tracer.CurrentSpan.Context.SpanId); // If a tasks tag is inlucded in the tag list, we can either have included or excluded it. if (Config.ExludeTags) { if (Config.WithTags.Any(t => t.Equals(Tag, StringComparison.InvariantCultureIgnoreCase))) { l($"Skipping task {GetType().Name} because it's negated with tags (NOT {String.Join(',', Config.WithTags)})"); return; } } else if (Config.WithTags.Count > 0 && !Config.WithTags.Any(t => t.Equals(Tag, StringComparison.InvariantCultureIgnoreCase))) { l($"Skipping task {GetType().Name} (with tag {Tag}) because it's not included in to run tags ({String.Join(',', Config.WithTags)})"); return; } // Should we run the validation checks? var hasValidation = typeof(IValidation).IsAssignableFrom(this.GetType()); if (hasValidation && Config.Validate) { act?.SetTag("validated", true); await((IValidation)this).Validate(); } // If we're in a run to only validate the config, don't change things if (!Config.OnlyValidate) { await Do(); } ReportRateLimits(); }
private static void ProcessRequest(HttpWebRequest request) { if (!WebRequestActivitySource.HasListeners() || IsRequestInstrumented(request)) { // No subscribers to the ActivitySource or this request was instrumented by previous // ProcessRequest, such is the case with redirect responses where the same request is sent again. return; } var activity = WebRequestActivitySource.StartActivity(ActivityName, ActivityKind.Client); if (activity == null) { // There is a listener but it decided not to sample the current request. return; } IAsyncResult asyncContext = writeAResultAccessor(request); if (asyncContext != null) { // Flow here is for [Begin]GetRequestStream[Async]. AsyncCallbackWrapper callback = new AsyncCallbackWrapper(request, activity, asyncCallbackAccessor(asyncContext)); asyncCallbackModifier(asyncContext, callback.AsyncCallback); } else { // Flow here is for [Begin]GetResponse[Async] without a prior call to [Begin]GetRequestStream[Async]. asyncContext = readAResultAccessor(request); AsyncCallbackWrapper callback = new AsyncCallbackWrapper(request, activity, asyncCallbackAccessor(asyncContext)); asyncCallbackModifier(asyncContext, callback.AsyncCallback); } AddRequestTagsAndInstrumentRequest(request, activity); }
public void IHttpActivityFeatureIsAssignedToIfItExists() { var testSource = new ActivitySource(Path.GetRandomFileName()); var dummySource = new ActivitySource(Path.GetRandomFileName()); using var listener = new ActivityListener { ShouldListenTo = activitySource => (ReferenceEquals(activitySource, testSource) || ReferenceEquals(activitySource, dummySource)), Sample = (ref ActivityCreationOptions <ActivityContext> _) => ActivitySamplingResult.AllData }; ActivitySource.AddActivityListener(listener); var hostingApplication = CreateApplication(activitySource: testSource); var httpContext = new DefaultHttpContext(); httpContext.Features.Set <IHttpActivityFeature>(new TestHttpActivityFeature()); var context = hostingApplication.CreateContext(httpContext.Features); var activityFeature = context.HttpContext.Features.Get <IHttpActivityFeature>(); Assert.NotNull(activityFeature); Assert.IsType <TestHttpActivityFeature>(activityFeature); Assert.NotNull(activityFeature.Activity); Assert.Equal(HostingApplicationDiagnostics.ActivityName, activityFeature.Activity.DisplayName); var initialActivity = Activity.Current; // Create nested dummy Activity using var _ = dummySource.StartActivity("DummyActivity"); Assert.Same(initialActivity, activityFeature.Activity); Assert.NotEqual(Activity.Current, activityFeature.Activity); // Act/Assert hostingApplication.DisposeContext(context, null); }
public void ProcessorDoesNotBlockOnExporter() { var activityExporter = new TestActivityExporter(async _ => await Task.Delay(500)); using var openTelemetry = Sdk.CreateTracerProviderBuilder() .AddSource("random") .AddProcessor(new SimpleActivityProcessor(activityExporter)) .Build(); ActivitySource source = new ActivitySource("random"); var activity = source.StartActivity("somename"); // does not block var sw = Stopwatch.StartNew(); activity.Stop(); sw.Stop(); Assert.InRange(sw.Elapsed, TimeSpan.Zero, TimeSpan.FromMilliseconds(100)); var exported = this.WaitForSpans(activityExporter, 1, TimeSpan.FromMilliseconds(600)); Assert.Single(exported); }
public void CheckingCustomActivityProcessor() { const string ActivitySourceName = "zpages.test"; Guid requestId = Guid.NewGuid(); TestActivityProcessor testActivityProcessor = new TestActivityProcessor(); bool startCalled = false; bool endCalled = false; testActivityProcessor.StartAction = (a) => { startCalled = true; }; testActivityProcessor.EndAction = (a) => { endCalled = true; }; using var tracerProvider = Sdk.CreateTracerProviderBuilder() .AddSource(ActivitySourceName) .AddProcessor(testActivityProcessor) .AddZPagesExporter() .Build(); using var source = new ActivitySource(ActivitySourceName); using var activity = source.StartActivity("Test Zipkin Activity"); activity?.Stop(); Assert.True(startCalled); Assert.True(endCalled); ZPagesActivityTracker.Reset(); }
public void TestActivitySourceAttachedObject() { RemoteExecutor.Invoke(() => { // All Activities created through the constructor should have same source. Assert.True(object.ReferenceEquals(new Activity("a1").Source, new Activity("a2").Source)); Assert.Equal("", new Activity("a3").Source.Name); Assert.Equal(string.Empty, new Activity("a4").Source.Version); using ActivitySource aSource = new ActivitySource("SourceToTest", "1.2.3.4"); // Ensure at least we have a listener to allow Activity creation using ActivityListener listener = new ActivityListener(); listener.ActivityStarted = activity => Assert.NotNull(activity); listener.ActivityStopped = activity => Assert.NotNull(activity); listener.ShouldListenTo = (activitySource) => object.ReferenceEquals(aSource, activitySource); listener.GetRequestedDataUsingParentId = (ref ActivityCreationOptions <string> activityOptions) => ActivityDataRequest.AllData; listener.GetRequestedDataUsingContext = (ref ActivityCreationOptions <ActivityContext> activityOptions) => ActivityDataRequest.AllData; ActivitySource.AddActivityListener(listener); using Activity activity = aSource.StartActivity("ActivityToTest"); Assert.True(object.ReferenceEquals(aSource, activity.Source)); }).Dispose(); }
public async Task SendMessage <T> (T messageBody) where T : class { var producerTopic = configuration.GetSection("ProducerTopic").Value; var activityName = $"{producerTopic} send"; var props = new BasicProperties(); using (var activity = ActivitySource.StartActivity(activityName, ActivityKind.Producer)) { if (activity != null) { TextFormat.Inject(activity.Context, props, this.InjectTraceContextIntoBasicProperties); AddMessagingTags(activity); using (var producer = new ProducerBuilder <Null, T> (producerConfig).Build()) { try { var dr = await producer.ProduceAsync(producerTopic, new Message <Null, T> { Value = messageBody, Headers = props.Headers }); } catch (ProduceException <Null, string> e) { Console.WriteLine($"Delivery failed: {e.Error.Reason}"); } } } } }
public void ProcessorDoesNotBlockOnExporter() { this.activityExporter = new TestActivityExporter(async _ => await Task.Delay(500)); this.openTelemetry = OpenTelemetrySdk.CreateTracerProvider(b => b .AddActivitySource("cijo") .AddProcessorPipeline(p => p .SetExporter(this.activityExporter) .SetExportingProcessor(e => new SimpleActivityProcessor(e)))); ActivitySource source = new ActivitySource("cijo"); var activity = source.StartActivity("somename"); // does not block var sw = Stopwatch.StartNew(); activity.Stop(); sw.Stop(); Assert.InRange(sw.Elapsed, TimeSpan.Zero, TimeSpan.FromMilliseconds(100)); var exported = this.WaitForSpans(this.activityExporter, 1, TimeSpan.FromMilliseconds(600)); Assert.Single(exported); }
public static void Main() { using var tracerProvider = Sdk.CreateTracerProviderBuilder() .AddSource("OTel.Demo") .Build(); using var loggerFactory = LoggerFactory.Create(builder => { builder .AddJsonConsole(options => { options.IncludeScopes = true; }) .Configure(options => options.ActivityTrackingOptions = ActivityTrackingOptions.TraceId | ActivityTrackingOptions.SpanId); }); var logger = loggerFactory.CreateLogger <Program>(); logger.LogInformation("Hello, World!"); using (var activity = DemoSource.StartActivity("Foo")) { logger.LogInformation("Hello, World!"); } }
public async Task Invoke(HttpContext context) { // Get the scoped instance of the container! IContainerResolve container = (IContainerResolve)context.RequestServices.GetService(typeof(IContainerResolve)); var logger = container.Resolve <ILogger <ClaimsPrincipalMiddleware> >(); try { // if we have some part of the site not in MVC (like swagger) and we need to force // authentication. We can add the start of the path to check and in this case we force a login! if (null != context.User && !context.User.Identity.IsAuthenticated) { if (_option.OpenIdOptions.ForceAuthenticationForPaths.Any(r => { return(r.Last().Equals('*') ? context.Request.Path.Value.StartsWith(r.Remove(r.Length - 1), StringComparison.InvariantCultureIgnoreCase) : context.Request.Path.Value.Equals(r, StringComparison.InvariantCultureIgnoreCase)); })) { logger.Technical().System("Force an OpenId connection.").Log(); var cleanUri = new Uri(new Uri(context.Request.GetEncodedUrl()).GetLeftPart(UriPartial.Path)); if (Uri.TryCreate(_option.RedirectAuthority, UriKind.Absolute, out var authority)) { cleanUri = new Uri(authority, cleanUri.AbsolutePath); } var properties = new AuthenticationProperties() { RedirectUri = cleanUri.ToString() }; await context.ChallengeAsync(OpenIdConnectDefaults.AuthenticationScheme, properties); return; } } if (null != context.User && context.User.Identity.IsAuthenticated) { logger.Technical().System("Create the principal.").Log(); // Add Telemetry. using (var activity = _activitySource?.StartActivity("Create Arc4u Principal", ActivityKind.Producer)) { // As the extension point can use some ITokenProvider based on the user. // A dummy Principal is created based on the context identity! // Must be registered as Scoped! if (container.TryResolve <IApplicationContext>(out var applicationContext)) { applicationContext.SetPrincipal(new AppPrincipal(new Authorization(), context.User.Identity, "S-1-0-0")); } // Load Claims from an external source if necessary! if (_option.ClaimsFillerOptions.LoadClaimsFromClaimsFillerProvider) { await LoadExtraClaimsAsync(context, container, logger); } // Build an AppPrincipal. AppPrincipal principal = null; var profileFiller = container.Resolve <IClaimProfileFiller>(); var authorizationFiller = container.Resolve <IClaimAuthorizationFiller>(); var authorization = authorizationFiller.GetAuthorization(context.User.Identity); var profile = profileFiller.GetProfile(context.User.Identity); principal = new AppPrincipal(authorization, context.User.Identity, profile.Sid) { Profile = profile }; // Check if we have an ActivityID. var activityIdHeader = context.Request?.Headers?.FirstOrDefault(h => h.Key.Equals("activityid", StringComparison.InvariantCultureIgnoreCase)); if (null == activityIdHeader || !activityIdHeader.HasValue || String.IsNullOrWhiteSpace(activityIdHeader.Value.Key) || StringValues.Empty == activityIdHeader.Value || activityIdHeader.Value.Value.Count == 0) { principal.ActivityID = Guid.NewGuid(); } else { Guid activityId = Guid.Empty; if (Guid.TryParse(activityIdHeader.Value.Value[0], out activityId) && activityId != Guid.Empty) { logger.Technical().Information($"Set the activity to the principal based on the caller information: {activityId}.").Log(); } else { logger.Technical().Information($"The activity id given by the caller is not a valid Guid. A new one has been assigned.").Log(); activityId = Guid.NewGuid(); } principal.ActivityID = activityId; } activity?.AddTag(LoggingConstants.ActivityId, principal.ActivityID); // Check for a culture. var cultureHeader = context.Request?.Headers?.FirstOrDefault(h => h.Key.Equals("culture", StringComparison.InvariantCultureIgnoreCase)); if (null != cultureHeader && cultureHeader.HasValue && StringValues.Empty != activityIdHeader.Value && cultureHeader.Value.Value.Count > 0) { try { principal.Profile.CurrentCulture = new CultureInfo(cultureHeader.Value.Value[0]); } catch (Exception ex) { logger.Technical().Exception(ex).Log(); } } logger.Technical().System("Set AppPrincipal to the HttpContext.User.").Log(); context.User = principal; if (null != applicationContext) { logger.Technical().System("Set AppPrincipal to the ApplicationContext.").Log(); applicationContext.SetPrincipal(principal); } } } } catch (Exception ex) { logger.Technical().Exception(ex).Log(); } await _next(context); }
public static async Task <IActionResult> Run( [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req, ILogger log) { ObjectResult result = null; using (var activity = MyActivitySource.StartActivity("Foo", ActivityKind.Server, req.Headers["traceparent"])) { if (activity.ParentId != null) { Console.WriteLine("Parentid is" + activity.ParentId); } activity?.SetTag("enviroment", "Shabuhabs.AzureFunctions-central-sub1"); activity?.SetTag("Fooz-Functionz", "OTel .NET Rocks!"); var startTime = DateTimeOffset.Now; string name = req.Query["name"]; string requestBody = await new StreamReader(req.Body).ReadToEndAsync(); dynamic data = JsonConvert.DeserializeObject(requestBody); name ??= data?.name; log.LogInformation("Foo Function is Running . .. . HttpTrigger"); activity?.SetTag("query.name", name ?? "no-name"); string responseMessage = string.IsNullOrEmpty(name) ? "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response." : $"Hello, {name}. This HTTP triggered function executed successfully."; try { // Used to simulate errors only !! ( send in name=crash or name=slow) if (name == "crash") { throw new ArgumentException("CRASHED, 'crash' is invalid arg!"); } else if (name == "slow") { System.Threading.Thread.Sleep(4000); } result = new OkObjectResult(responseMessage); activity?.SetTag("http.status_code", 200); activity?.SetTag("error", false); } catch (Exception e) { result = new ExceptionResult(e, includeErrorDetail: true); activity?.SetTag("error.message", e.Message); activity?.SetTag("http.status_code", 500); activity?.SetTag("error", true); log.LogError("Foo Function FAIL!"); } finally { } } return(result); }
static async Task Main(string[] args) { var opts = new OptionSet() { { "u|user="******"(REQUIRED) A github user with admin access.", u => Config.Github.User = u } , { "t|token=", "(REQUIRED) A github token that has admin access to the org.", t => Config.Github.Token = t } , { "o|org=", "The organization we need to run the actions against (defaults to `sectigo-eng`)", o => Config.Github.Org = o } , { "teams=", "A file with the desired team structure in JSON format. If this is set, this will enforce that team structure (including removing members from teams). We expect a Dictionary where the key is the team name, and the value a list of string with the user login names.", ts => Config.TeamStructureFile = ts } , { "repos=", "A file with the desired repository teams access in JSON format.", rs => Config.RepoStructureFile = rs } , { "report=", "The path were we output the audit report. This defaults to ./", o => Config.ReportingPath = o } , { "d|dryrun=", "Should this run authoritative updates (`no`-dryrun), or only display changes (`yes`.Run a dryrun please). Must be either 'yes' or 'no'. Defaults to 'yes'.", (string dry) => Config.DryRunMode = dry.ToLower() } , { "no-dryrun", "Run authoritative updates. This can be destructive. This is the greedy option over --dryrun=yes|no.", d => Config.DryRunMode = "no" } , { "validate=", "Should this run include validation checks .Runes X exist or not). Excluding these (or `only` running these) saves significant api hits for rate limiting. Must be either `yes` or `no` or `only`. Defaults to `yes`", (string val) => Config.ValidationMode = val.ToLower() } , { "tags=", "Only runs the tasks listed here. Note that if this argument is specified, and is inclusive, any tasks that do not have tags will not be run. Expects a CSV. By default everything runs. Current options are `OnlyTeams`", tags => Config.WithTags = new List <string>(tags.Split(',').Where(s => !string.IsNullOrWhiteSpace(s))) } , { "e=", "Can only be used with --tags. While exclude any tags listed from the current run. Can be used as a flag, or value of `yes` or `no` Defaults to off.)", (string exclude) => Config.ExludeTagsMode = exclude } , { "contextPath=", "If set, will load all the supported manifests (yaml or yml) from that directory, and those will apply to the settings. Path has to exists.", c => Config.ContextPath = c } , { "h|help", p => Config.Help = true } }; try { opts.Parse(args); Console.WriteLine($"Current configuration: {Config.ToString()}"); } catch (OptionException e) { Console.WriteLine(e.Message); return; } if (!Config.ValidateInput() || Config.Help) { opts.WriteOptionDescriptions(Console.Out); return; } if (Config.Honeycomb.Validate()) { Console.WriteLine("Setting up telemetry"); source = new ActivitySource("gitman.App", "1.0.0"); tracer = Sdk .CreateTracerProviderBuilder() .AddHoneycomb(new HoneycombOptions { ServiceName = Config.Honeycomb.ServiceName, ApiKey = Config.Honeycomb.ApiKey, Dataset = Config.Honeycomb.Dataset }) .AddSource("gitman.*") .Build(); } using var root = source?.StartActivity("app"); if (!Config.DryRun) { Console.WriteLine("\n\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); Console.WriteLine("!!! Non-DryRun mode !!!"); if (Config.OnlyValidate) { Console.WriteLine("!!! But w're only running in validation mode, so there shouldn't be changes. !!!"); } else { Console.WriteLine("!!! Changes WILL BE authorative !!!"); } Console.WriteLine("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n\n"); } // For the github sdk to allow us to specify our GithubHttpCache, we have to add all this other // nonsense to it. client = new GitHubClient(new Connection( new ProductHeaderValue("SuperMassiveCLI") , GitHubClient.GitHubApiUrl , new InMemoryCredentialStore(Credentials.Anonymous) // this is the only thing that really matters in this instantiation. There is no other way // to set this up. , new Octokit.Internal.HttpClientAdapter(() => new Helpers.GithubHttpCache()) , new Octokit.Internal.SimpleJsonSerializer() )); client.Credentials = new Credentials(Config.Github.User, Config.Github.Token); var loader = new ResourceLoader(); if (!string.IsNullOrEmpty(Config.ContextPath)) { loader.LoadResources(Config.ContextPath); } Console.WriteLine("\n\nChecking merge setting"); await new Merging { Client = client, Loader = loader }.Run(); Console.WriteLine("\n\nChecking branch protections"); await new Protection() { Client = client, Loader = loader }.Run(); Console.WriteLine("\n\nPerforming team audit"); var audit = new Audit(outputPath: Config.ReportingPath) { Client = client }; await audit.Run(); if (Config.HasTeamsStructureFile) { var repository_description = GetRepositoryDescription(); var proposed_teams = GetTeams(); Console.WriteLine($"\n\nChecking for solo collaborators"); await new OnlyTeams(repository_description, proposed_teams) { Client = client }.Run(); Console.WriteLine("\n\nChecking teams"); await new Teams(proposed_teams) { Client = client }.Run(); Console.WriteLine("\n\nChecking teams memberships"); await new TeamMemberships(proposed_teams) { Client = client }.Run(); if (Config.HasRepoStructureFile) { Console.WriteLine("\n\nChecking collaborators repository access"); await new RepositoryAccess(repository_description, proposed_teams.Keys) { Client = client }.Run(); } } }
public static Activity CreateActivityWithKind(ActivitySource source) { var activity = source.StartActivity("name", ActivityKind.Client); return(activity); }
private static async Task RunAsync() { var endpoint = "/delay/5ms"; using var listener = new HttpEventListener(); source = new ActivitySource("http-client-test"); var serviceCollection = new ServiceCollection(); serviceCollection.AddHttpOptionsTelemetry(builder => builder.AddConsoleExporter()); serviceCollection.AddHttpClientOptions(options => { options.ServiceName = "service"; options.Handler.MaxConnection = 500; _server.ConfigureWireMockServer(options); }); var services = serviceCollection.BuildServiceProvider(); await Task.WhenAll(services.GetServices <IHostedService>() .Select(e => e.StartAsync(CancellationToken.None))); var factory = services.GetRequiredService <IHttpClientFactory>(); var client = factory.CreateClient("service"); var stopwatch = Stopwatch.StartNew(); Console.WriteLine("oooo: "); do { try { await client.GetAsync(endpoint).ConfigureAwait(false); } catch (Exception e) { } } while (Console.ReadKey().Key != ConsoleKey.Escape); do { try { var activityLinks = new List <ActivityLink>(); var initialTags = new ActivityTagsCollection(); initialTags["com.mycompany.product.mytag1"] = "tagValue1"; initialTags["com.mycompany.product.mytag2"] = "tagValue2"; var linkedContext1 = new ActivityContext( ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.None); var linkedContext2 = new ActivityContext( ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.Recorded); activityLinks.Add(new ActivityLink(linkedContext1)); activityLinks.Add(new ActivityLink(linkedContext2)); using var activity = source.StartActivity( "ActivityWithLinks", ActivityKind.Server, default(ActivityContext), initialTags, activityLinks); var latencyStats = await TrafficGenerator .GenerateTraffic(100, () => client.GetAsync(endpoint)) .Latency() .TakeUntil(DateTimeOffset.Now.AddSeconds(20)); Console.WriteLine(latencyStats.Print()); await client.GetAsync(endpoint).ConfigureAwait(false); System.Console.WriteLine("Press Enter key to continue."); } catch (Exception e) { Console.WriteLine(e); throw; } } while (Console.ReadKey().Key != ConsoleKey.Escape); }
internal static object Run(ConsoleOptions options) { // Enable OpenTelemetry for the source "MyCompany.MyProduct.MyWebServer" // and use a single pipeline with a custom MyProcessor, and Console exporter. using var openTelemetry = OpenTelemetrySdk.EnableOpenTelemetry( (builder) => builder.AddActivitySource("MyCompany.MyProduct.MyWebServer") .SetResource(Resources.CreateServiceResource("MyServiceName")) .UseConsoleExporter(opt => opt.DisplayAsJson = options.DisplayAsJson, (p) => p.AddProcessor((next) => new MyProcessor(next)))); // The above line is required only in applications // which decide to use Open Telemetry. // Libraries would simply write the following lines of code to // emit activities, which are the .NET representation of OT Spans. var source = new ActivitySource("MyCompany.MyProduct.MyWebServer"); // The below commented out line shows more likely code in a real world webserver. // using (var parent = source.StartActivity("HttpIn", ActivityKind.Server, HttpContext.Request.Headers["traceparent"] )) using (var parent = source.StartActivity("HttpIn", ActivityKind.Server)) { // TagNames can follow the OT guidelines // from https://github.com/open-telemetry/opentelemetry-specification/tree/master/specification/trace/semantic_conventions parent?.AddTag("http.method", "GET"); parent?.AddTag("http.host", "MyHostName"); if (parent != null) { parent.DisplayName = "HttpIn DisplayName"; // IsAllDataRequested is equivalent of Span.IsRecording if (parent.IsAllDataRequested) { parent.AddTag("expensive data", "This data is expensive to obtain. Avoid it if activity is not being recorded"); } } try { // Actual code to achieve the purpose of the library. // For websebserver example, this would be calling // user middlware pipeline. // There can be child activities. // In this example HttpOut is a child of HttpIn. using (var child = source.StartActivity("HttpOut", ActivityKind.Client)) { child?.AddTag("http.url", "www.mydependencyapi.com"); try { // do actual work. child?.AddEvent(new ActivityEvent("sample activity event.")); child?.AddTag("http.status_code", "200"); } catch (Exception) { child?.AddTag("http.status_code", "500"); } } parent?.AddTag("http.status_code", "200"); } catch (Exception) { parent?.AddTag("http.status_code", "500"); } } System.Console.WriteLine("Press Enter key to exit."); return(null); }
public override async Task <HelloReply> SayHello(HelloRequest request, ServerCallContext context) { // check inputs if (context.Deadline == DateTime.MaxValue) { // enforce deadline context.Status = new Status(StatusCode.Cancelled, "No Deadline Supplied"); _logger.LogWarning("Caller '{Peer}' Omitted Deadline", context.Peer); } else if (string.IsNullOrWhiteSpace(request.Name)) { // require name context.Status = new Status(StatusCode.InvalidArgument, "'Name' is Required"); } else if (request.Name.Equals("Mud", StringComparison.InvariantCultureIgnoreCase)) { // Does anyone else remember this song? context.Status = new Status(StatusCode.InvalidArgument, "Your name is not Mud"); } // are we OK? if (context.Status.StatusCode != StatusCode.OK) { // record validation failure as trace event Activity.Current?.AddEvent(new ActivityEvent(context.Status.ToString())); if (context.Status.StatusCode == StatusCode.InvalidArgument) { _logger.LogWarning("Input Validation Failed: {@Request}", request); } return(null); } // try to get our reply from the cache using (Activity tryCacheActivity = _activitySource.StartActivity("Check-Cache")) { tryCacheActivity?.AddTag("cache.searchKey", request.Name); HelloReply cacheHit = await _cache.GetProto <HelloReply>(request.Name); if (cacheHit != null) { tryCacheActivity?.AddTag("cache.result", "hit"); return(cacheHit); } tryCacheActivity?.AddTag("cache.result", "miss"); } // build new record add to database var record = new GreetingRecord { Name = request.Name, Utc = DateTime.UtcNow }; using (Activity insertActivity = _activitySource.StartActivity("Insert-Sql-Record")) { int recId = await _repository.InsertGreeting(record, context.CancellationToken); insertActivity?.AddTag("record.id", recId.ToString()); _logger.LogInformation("Inserted new greeting record {@record}", record); } // create reply and add to cache var reply = new HelloReply { Message = $"{record.Name} said hello at {record.Utc:HH:mm:ss.fff} UTC." }; using (_activitySource.StartActivity("Add-To-Cache")) await _cache.SetProto(request.Name, reply, TimeSpan.FromMinutes(1)); // OK return(reply); }
internal static Activity CreateTestActivity( bool setAttributes = true, Dictionary <string, object> additionalAttributes = null, bool addEvents = true, bool addLinks = true, Resource resource = null, ActivityKind kind = ActivityKind.Client) { var startTimestamp = DateTime.UtcNow; var endTimestamp = startTimestamp.AddSeconds(60); var eventTimestamp = DateTime.UtcNow; var traceId = ActivityTraceId.CreateFromString("e8ea7e9ac72de94e91fabc613f9686b2".AsSpan()); var parentSpanId = ActivitySpanId.CreateFromBytes(new byte[] { 12, 23, 34, 45, 56, 67, 78, 89 }); var attributes = new Dictionary <string, object> { { "stringKey", "value" }, { "longKey", 1L }, { "longKey2", 1 }, { "doubleKey", 1D }, { "doubleKey2", 1F }, { "boolKey", true }, { "int_array", new int[] { 1, 2 } }, { "bool_array", new bool[] { true, false } }, { "double_array", new double[] { 1.0, 1.1 } }, { "string_array", new string[] { "a", "b" } }, }; if (additionalAttributes != null) { foreach (var attribute in additionalAttributes) { attributes.Add(attribute.Key, attribute.Value); } } var events = new List <ActivityEvent> { new ActivityEvent( "Event1", eventTimestamp, new ActivityTagsCollection(new Dictionary <string, object> { { "key", "value" }, })), new ActivityEvent( "Event2", eventTimestamp, new ActivityTagsCollection(new Dictionary <string, object> { { "key", "value" }, })), }; var linkedSpanId = ActivitySpanId.CreateFromString("888915b6286b9c41".AsSpan()); var activitySource = new ActivitySource(nameof(CreateTestActivity)); var tags = setAttributes ? attributes : null; var links = addLinks ? new[] { new ActivityLink(new ActivityContext( traceId, linkedSpanId, ActivityTraceFlags.Recorded)), } : null; var activity = activitySource.StartActivity( "Name", kind, parentContext: new ActivityContext(traceId, parentSpanId, ActivityTraceFlags.Recorded), tags, links, startTime: startTimestamp); if (addEvents) { foreach (var evnt in events) { activity.AddEvent(evnt); } } activity.SetEndTime(endTimestamp); activity.Stop(); return(activity); }
public void ToOtlpSpanTest() { var activitySource = new ActivitySource(nameof(this.ToOtlpSpanTest)); using var rootActivity = activitySource.StartActivity("root", ActivityKind.Producer); var attributes = new List <KeyValuePair <string, object> > { new KeyValuePair <string, object>("bool", true), new KeyValuePair <string, object>("long", 1L), new KeyValuePair <string, object>("string", "text"), new KeyValuePair <string, object>("double", 3.14), new KeyValuePair <string, object>("int", 1), new KeyValuePair <string, object>("datetime", DateTime.UtcNow), new KeyValuePair <string, object>("bool_array", new bool[] { true, false }), new KeyValuePair <string, object>("int_array", new int[] { 1, 2 }), new KeyValuePair <string, object>("double_array", new double[] { 1.0, 2.09 }), new KeyValuePair <string, object>("string_array", new string[] { "a", "b" }), }; foreach (var kvp in attributes) { rootActivity.SetTag(kvp.Key, kvp.Value); } var startTime = new DateTime(2020, 02, 20, 20, 20, 20, DateTimeKind.Utc); DateTimeOffset dateTimeOffset; #if NET452 dateTimeOffset = DateTimeOffsetExtensions.FromUnixTimeMilliseconds(0); #else dateTimeOffset = DateTimeOffset.FromUnixTimeMilliseconds(0); #endif var expectedUnixTimeTicks = (ulong)(startTime.Ticks - dateTimeOffset.Ticks); var duration = TimeSpan.FromMilliseconds(1555); rootActivity.SetStartTime(startTime); rootActivity.SetEndTime(startTime + duration); Span <byte> traceIdSpan = stackalloc byte[16]; rootActivity.TraceId.CopyTo(traceIdSpan); var traceId = traceIdSpan.ToArray(); var otlpSpan = rootActivity.ToOtlpSpan(); Assert.NotNull(otlpSpan); Assert.Equal("root", otlpSpan.Name); Assert.Equal(OtlpTrace.Span.Types.SpanKind.Producer, otlpSpan.Kind); Assert.Equal(traceId, otlpSpan.TraceId); Assert.Empty(otlpSpan.ParentSpanId); Assert.Null(otlpSpan.Status); Assert.Empty(otlpSpan.Events); Assert.Empty(otlpSpan.Links); AssertOtlpAttributes(attributes, otlpSpan.Attributes); var expectedStartTimeUnixNano = 100 * expectedUnixTimeTicks; Assert.Equal(expectedStartTimeUnixNano, otlpSpan.StartTimeUnixNano); var expectedEndTimeUnixNano = expectedStartTimeUnixNano + (duration.TotalMilliseconds * 1_000_000); Assert.Equal(expectedEndTimeUnixNano, otlpSpan.EndTimeUnixNano); var childLinks = new List <ActivityLink> { new ActivityLink(rootActivity.Context, new ActivityTagsCollection(attributes)) }; var childActivity = activitySource.StartActivity( "child", ActivityKind.Client, rootActivity.Context, links: childLinks); childActivity.SetStatus(Status.Error); var childEvents = new List <ActivityEvent> { new ActivityEvent("e0"), new ActivityEvent("e1", default, new ActivityTagsCollection(attributes))