Esempio n. 1
0
        public void Promote(string id)
        {
            ErrorStack entity = GetEntity(id);

            if (entity == null)
            {
                throw new HttpResponseException(base.NotFoundErrorResponseMessage(id));
            }

            if (!_billingManager.HasPremiumFeatures(entity.OrganizationId))
            {
                throw new HttpResponseException(PlanLimitReached("Promote to External is a premium feature used to promote an error stack to an external system. Please upgrade your plan to enable this feature."));
            }

            List <ProjectHook> promotedProjectHooks = _projectHookRepository.GetByProjectId(entity.ProjectId).Where(p => p.EventTypes.Contains(ProjectHookRepository.EventTypes.StackPromoted)).ToList();

            if (!promotedProjectHooks.Any())
            {
                throw new HttpResponseException(Request != null
                    ? Request.CreateErrorResponse(HttpStatusCode.NotImplemented, "No promoted web hooks are configured for this project. Please add a promoted web hook to use this feature.")
                    : new HttpResponseMessage(HttpStatusCode.NotImplemented));
            }

            using (IMessageProducer messageProducer = _messageFactory.CreateMessageProducer()) {
                foreach (ProjectHook hook in promotedProjectHooks)
                {
                    messageProducer.Publish(new WebHookNotification {
                        ProjectId = hook.ProjectId,
                        Url       = hook.Url,
                        Data      = WebHookErrorStack.FromErrorStack(entity, _projectRepository, _organizationRepository)
                    });
                }
            }
        }
        public override void Process(ErrorPipelineContext ctx)
        {
            var organization = _organizationRepository.GetByIdCached(ctx.Error.OrganizationId);

            // if they don't have premium features, then we don't need to queue notifications
            if (organization != null && !organization.HasPremiumFeatures)
            {
                return;
            }

            using (IMessageProducer messageProducer = _messageFactory.CreateMessageProducer()) {
                messageProducer.Publish(new ErrorNotification {
                    ErrorId      = ctx.Error.Id,
                    ErrorStackId = ctx.Error.ErrorStackId,
                    FullTypeName = ctx.StackingInfo.FullTypeName,
                    IsNew        = ctx.IsNew,
                    IsCritical   = ctx.Error.Tags != null && ctx.Error.Tags.Contains("Critical"),
                    IsRegression = ctx.IsRegression,
                    Message      = ctx.StackingInfo.Message,
                    ProjectId    = ctx.Error.ProjectId,
                    Code         = ctx.Error.Code,
                    UserAgent    = ctx.Error.RequestInfo != null ? ctx.Error.RequestInfo.UserAgent : null,
                    Url          = ctx.Error.RequestInfo != null ? ctx.Error.RequestInfo.GetFullPath(true, true) : null
                });

                foreach (ProjectHook hook in _projectHookRepository.GetByProjectId(ctx.Error.ProjectId))
                {
                    bool shouldCall = hook.EventTypes.Contains(ProjectHookRepository.EventTypes.NewError) && ctx.IsNew ||
                                      hook.EventTypes.Contains(ProjectHookRepository.EventTypes.ErrorRegression) && ctx.IsRegression ||
                                      hook.EventTypes.Contains(ProjectHookRepository.EventTypes.CriticalError) && ctx.Error.Tags != null && ctx.Error.Tags.Contains("Critical");

                    if (!shouldCall)
                    {
                        continue;
                    }

                    Log.Trace().Project(ctx.Error.ProjectId).Message("Web hook queued: project={0} url={1}", ctx.Error.ProjectId, hook.Url).Write();

                    messageProducer.Publish(new WebHookNotification {
                        ProjectId = ctx.Error.ProjectId,
                        Url       = hook.Url,
                        Data      = WebHookError.FromError(ctx, _projectRepository, _errorStackRepository, _organizationRepository)
                    });
                }
            }
        }
Esempio n. 3
0
        public override HttpResponseMessage Post(Error value)
        {
            if (value == null)
            {
                return(Request.CreateErrorResponse(HttpStatusCode.BadRequest, "Invalid error posted."));
            }

            _stats.Counter(StatNames.ErrorsSubmitted);

            if (User != null && User.Project != null)
            {
                value.ProjectId      = User.Project.Id;
                value.OrganizationId = User.Project.OrganizationId;
            }

            if (value.OccurrenceDate == DateTimeOffset.MinValue)
            {
                value.OccurrenceDate = DateTimeOffset.UtcNow;
            }

            string message = User == null?String.Format("Inserting error '{0}'.", value.Id) : String.Format("Inserting error '{0}' with API key '{1}'.", value.Id, User.Identity.Name);

            if (value.RequestInfo != null)
            {
                message += String.Format(" IP Address: {0}.", value.RequestInfo.ClientIpAddress);
            }
            if (value.ExceptionlessClientInfo != null)
            {
                message += String.Format(" Client Version: {0}.", value.ExceptionlessClientInfo.Version);
            }
            Log.Debug().Message(message).Write();

            if (String.IsNullOrWhiteSpace(value.OrganizationId) || !User.IsInOrganization(value.OrganizationId))
            {
                return(InvalidOrganizationErrorResponseMessage());
            }

            string id = value.Id;

            if (String.IsNullOrEmpty(id))
            {
                value.Id = ObjectId.GenerateNewId().ToString();
                id       = value.Id;
            }

            if (_messageFactory != null)
            {
                using (IMessageProducer messageProducer = _messageFactory.CreateMessageProducer()) {
                    RetryUtil.Retry(() => messageProducer.Publish(value));
                    _stats.Counter(StatNames.ErrorsQueued);
                }
            }
            else
            {
                Log.Error().Message("Message Factory is null").Write();
            }

            if (Request == null)
            {
                return(CreatedResponseMessage());
            }

            HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created);

            response.Headers.Location = new Uri(Url.Link("DefaultApi", new { id }));
            return(response);
        }
Esempio n. 4
0
        public override JobResult Run(JobContext context)
        {
            Log.Info().Message("Daily Notification job starting").Write();

            if (!Settings.Current.EnableSummaryNotifications)
            {
                return(new JobResult {
                    Result = "Summary Notifications are disabled.",
                    Cancelled = true
                });
            }

            const int BATCH_SIZE = 25;

            // Send an email at 9:00am in the projects local time.
            IMongoQuery   query  = Query.LT(ProjectRepository.FieldNames.NextSummaryEndOfDayTicks, new BsonInt64(DateTime.UtcNow.Ticks - (TimeSpan.TicksPerHour * 9)));
            UpdateBuilder update = Update.Inc(ProjectRepository.FieldNames.NextSummaryEndOfDayTicks, TimeSpan.TicksPerDay);

            var projects = _projectRepository.Collection.FindAs <Project>(query).SetFields(ProjectRepository.FieldNames.Id, ProjectRepository.FieldNames.NextSummaryEndOfDayTicks).SetLimit(BATCH_SIZE).ToList();

            while (projects.Count > 0)
            {
                IMongoQuery queryWithProjectIds = Query.And(Query.In(ProjectRepository.FieldNames.Id, projects.Select(p => new BsonObjectId(new ObjectId(p.Id)))), query);
                var         result = _projectRepository.Collection.Update(queryWithProjectIds, update, UpdateFlags.Multi);
                Log.Info().Message("Daily Notification job processing {0} projects. Successfully updated {1} projects. ", projects.Count, result.DocumentsAffected);

                Debug.Assert(projects.Count == result.DocumentsAffected);

                foreach (var project in projects)
                {
                    var utcStartTime = new DateTime(project.NextSummaryEndOfDayTicks - TimeSpan.TicksPerDay);
                    if (utcStartTime < DateTime.UtcNow.Date.SubtractDays(2))
                    {
                        Log.Info().Message("Skipping Summary Notification older than two days for Project: {0} with a start time of {1}.", project.Id, utcStartTime);
                        continue;
                    }

                    if (_messageFactory != null)
                    {
                        using (IMessageProducer messageProducer = _messageFactory.CreateMessageProducer()) {
                            var notification = new SummaryNotification {
                                Id           = project.Id,
                                UtcStartTime = utcStartTime,
                                UtcEndTime   = new DateTime(project.NextSummaryEndOfDayTicks - TimeSpan.TicksPerSecond)
                            };

                            Log.Info().Message("Publishing Summary Notification for Project: {0}, with a start time of {1} and an end time of {2}", notification.Id, notification.UtcStartTime, notification.UtcEndTime);
                            messageProducer.Publish(notification);
                        }
                    }
                    else
                    {
                        Log.Error().Message("Message Factory is null").Write();
                    }
                }

                projects = _projectRepository.Collection.FindAs <Project>(query).SetFields(ProjectRepository.FieldNames.Id, ProjectRepository.FieldNames.NextSummaryEndOfDayTicks).SetLimit(BATCH_SIZE).ToList();
            }

            return(new JobResult {
                Result = "Successfully enforced all retention limits."
            });
        }