public void TryPublish(HttpServiceRequest requestData, Exception ex, ServiceMethod serviceMethod,
                               double requestTime)
        {
            var callEvent = _eventPublisher.CreateEvent();

            callEvent.CalledServiceName = serviceMethod?.GrainInterfaceType.Name;
            callEvent.ClientMetadata    = requestData.TracingData;
            callEvent.ServiceMethod     = requestData.Target?.MethodName;

            var metaData  = _serviceEndPointDefinition.GetMetaData(serviceMethod);
            var arguments = (requestData.Arguments ?? new OrderedDictionary()).Cast <DictionaryEntry>();
            var @params   = new List <Param>();

            foreach (var argument in arguments)
            {
                foreach (var(name, value, sensitivity) in ExtractParamValues(argument, metaData))
                {
                    @params.Add(new Param {
                        Name  = name,
                        Value = value is string?value.ToString() : JsonConvert.SerializeObject(value),
                                    Sensitivity = sensitivity
                    });
                }
            }

            callEvent.Params          = @params;
            callEvent.Exception       = ex;
            callEvent.ActualTotalTime = requestTime;
            callEvent.ErrCode         = ex != null ? null : (int?)0;

            _eventPublisher.TryPublish(callEvent);
        }
        public async Task Invoke(IIncomingGrainCallContext context)
        {
            bool isOrleansGrain = context.InterfaceMethod == null || context.InterfaceMethod.DeclaringType == null || context.InterfaceMethod.Module.Assembly.FullName.StartsWith("Orleans");
            //TODO add test that validate that we are not introducing new grain in micro dot
            bool isMicrodotGrain = isOrleansGrain == false && context.InterfaceMethod.DeclaringType.Name == nameof(IRequestProcessingGrain);
            bool isServiceGrain  = isOrleansGrain == false && isMicrodotGrain == false;

            var grainTags = new Lazy <GrainTags>(() => new GrainTags(context));
            // Drop the request if we're overloaded
            var loadSheddingConfig = _loadSheddingConfig();

            if (
                (loadSheddingConfig.ApplyToMicrodotGrains && isMicrodotGrain) ||
                (loadSheddingConfig.ApplyToServiceGrains && isServiceGrain)
                )
            {
                //Can brake the flow by throwing Overloaded
                RejectRequestIfLateOrOverloaded(grainTags);
            }
            var loggingConfig = _grainLoggingConfig();

            bool shouldLog = (loggingConfig.LogOrleansGrains && isOrleansGrain) ||
                             (loggingConfig.LogMicrodotGrains && isMicrodotGrain) ||
                             (loggingConfig.LogServiceGrains && isServiceGrain);

            shouldLog = shouldLog && !ShouldSkipLoggingUnderRatio(loggingConfig, TracingContext.TryGetRequestID());
            GrainCallEvent grainEvent = null;

            if (shouldLog)
            {
                RequestTimings.GetOrCreate(); // Ensure request timings is created here and not in the grain call.
                RequestTimings.Current.Request.Start();
                grainEvent = _eventPublisher.CreateEvent();

                grainEvent.ParentSpanId = TracingContext.TryGetParentSpanID();
                grainEvent.SpanId       = Guid.NewGuid().ToString("N");
                TracingContext.SetParentSpan(grainEvent.SpanId);
            }

            Exception ex = null;

            try
            {
                await context.Invoke();
            }
            catch (Exception e)
            {
                ex = e;
                throw;
            }
            finally
            {
                if (shouldLog)
                {
                    RequestTimings.Current.Request.Stop();
                    PublishEvent(ex, grainTags, grainEvent);
                }
            }
        }
        private void PublishEvent(IGrainCallContext target, Exception ex)
        {
            var grainEvent = _eventPublisher.CreateEvent();

            if (target.Grain != null && target.Grain is ISystemTarget == false)
            {
                if (target.Grain?.GetPrimaryKeyString() != null)
                {
                    grainEvent.GrainKeyString = target.Grain.GetPrimaryKeyString();
                }
                else if (target.Grain.IsPrimaryKeyBasedOnLong())
                {
                    grainEvent.GrainKeyLong      = target.Grain.GetPrimaryKeyLong(out var keyExt);
                    grainEvent.GrainKeyExtention = keyExt;
                }
                else
                {
                    grainEvent.GrainKeyGuid      = target.Grain.GetPrimaryKey(out var keyExt);
                    grainEvent.GrainKeyExtention = keyExt;
                }

                if (target is Grain grainTarget)
                {
                    grainEvent.SiloAddress = grainTarget.RuntimeIdentity;
                }
            }


            grainEvent.SiloDeploymentId = _clusterIdentity.DeploymentId;
            grainEvent.TargetType       = target.Grain?.GetType().FullName ?? target.InterfaceMethod.DeclaringType?.FullName;
            grainEvent.TargetMethod     = target.InterfaceMethod.Name;
            grainEvent.Exception        = ex;
            grainEvent.ErrCode          = ex != null ? null : (int?)0;

            try
            {
                _eventPublisher.TryPublish(grainEvent);
            }
            catch (Exception)
            {
                EventsDiscarded.Increment();
            }
        }
        public void TryPublish(HttpServiceRequest requestData, Exception ex, ServiceMethod serviceMethod,
                               double requestTime)
        {
            var callEvent = _eventPublisher.CreateEvent();

            callEvent.CalledServiceName = serviceMethod?.GrainInterfaceType.Name;
            callEvent.ClientMetadata    = requestData.TracingData;
            callEvent.ServiceMethod     = requestData.Target?.MethodName;

            var metaData  = _serviceEndPointDefinition.GetMetaData(serviceMethod);
            var arguments = (requestData.Arguments ?? new OrderedDictionary()).Cast <DictionaryEntry>();

            callEvent.Params = arguments.SelectMany(_ => ExtractParamValues(_, metaData)).Select(_ => new Param {
                Name        = _.name,
                Value       = _.value,
                Sensitivity = _.sensitivity,
            });
            callEvent.Exception       = ex;
            callEvent.ActualTotalTime = requestTime;
            callEvent.ErrCode         = ex != null ? null : (int?)0;

            _eventPublisher.TryPublish(callEvent);
        }
Example #5
0
 /// <summary>
 /// Publishes (queues) an <see cref="EventData"/> instance using the specified <see cref="EventMetadata.Key"/>.
 /// </summary>
 /// <param name="eventPublisher">The <see cref="IEventPublisher"/>.</param>
 /// <param name="source">The event source.</param>
 /// <param name="subject">The event subject.</param>
 /// <param name="action">The event action.</param>
 /// <param name="key">The event key.</param>
 /// <returns>The <see cref="IEventPublisher"/> for fluent-style method-chaining.</returns>
 public static IEventPublisher Publish(this IEventPublisher eventPublisher, Uri source, string subject, string?action = null, params IComparable?[] key) => eventPublisher.Publish(eventPublisher.CreateEvent(source, subject, action, key));
Example #6
0
 /// <summary>
 /// Publishes (queues) an <see cref="EventData"/> instance (with no <see cref="EventMetadata.Key"/>).
 /// </summary>
 /// <param name="eventPublisher">The <see cref="IEventPublisher"/>.</param>
 /// <param name="source">The event source.</param>
 /// <param name="subject">The event subject.</param>
 /// <param name="action">The event action.</param>
 /// <returns>The <see cref="IEventPublisher"/> for fluent-style method-chaining.</returns>
 public static IEventPublisher Publish(this IEventPublisher eventPublisher, Uri source, string subject, string?action = null) => eventPublisher.Publish(eventPublisher.CreateEvent(source, subject, action));
 public ServiceCallEvent GetNewCallEvent()
 {
     return(_eventPublisher.CreateEvent());
 }