示例#1
0
        public override async Task EventBatchProcessingAsync(ICollection <EventContext> contexts)
        {
            var geoGroups = contexts.GroupBy(c => c.Event.Geo);

            foreach (var group in geoGroups)
            {
                GeoResult result;
                if (GeoResult.TryParse(group.Key, out result) && result.IsValid())
                {
                    group.ForEach(c => UpdateGeoAndlocation(c.Event, result, false));
                    continue;
                }

                // The geo coordinates are all the same, set the location from the result of any of the ip addresses.
                if (!String.IsNullOrEmpty(group.Key))
                {
                    var ips = group.SelectMany(c => c.Event.GetIpAddresses()).Union(new[] { group.First().EventPostInfo?.IpAddress }).Distinct();
                    result = await GetGeoFromIpAddressesAsync(ips).AnyContext();

                    group.ForEach(c => UpdateGeoAndlocation(c.Event, result));
                    continue;
                }

                // Each event could be a different user;
                foreach (var context in group)
                {
                    var ips = context.Event.GetIpAddresses().Union(new[] { context.EventPostInfo?.IpAddress });
                    result = await GetGeoFromIpAddressesAsync(ips).AnyContext();

                    UpdateGeoAndlocation(context.Event, result);
                }
            }
        }
示例#2
0
        public async Task ReverseGeocodeLookup()
        {
            var service = GetService <IGeocodeService>();

            if (service is NullGeocodeService)
            {
                return;
            }

            Assert.True(GeoResult.TryParse(GREEN_BAY_COORDINATES, out var coordinates));
            var location = await service.ReverseGeocodeAsync(coordinates.Latitude.GetValueOrDefault(), coordinates.Longitude.GetValueOrDefault());

            Assert.Equal("US", location?.Country);
            Assert.Equal("WI", location?.Level1);
            Assert.Equal("Brown County", location?.Level2);
            Assert.Equal("Green Bay", location?.Locality);
        }
示例#3
0
        public override async Task HandleItemAsync(WorkItemContext context)
        {
            var workItem = context.GetData <SetLocationFromGeoWorkItem>();

            GeoResult result;

            if (!GeoResult.TryParse(workItem.Geo, out result))
            {
                return;
            }

            var location = await _cacheClient.GetAsync <Location>(workItem.Geo, null).AnyContext();

            if (location == null)
            {
                try {
                    result = await _geocodeService.ReverseGeocodeAsync(result.Latitude.GetValueOrDefault(), result.Longitude.GetValueOrDefault()).AnyContext();

                    location = result.ToLocation();
                    await _metricsClient.CounterAsync(MetricNames.UsageGeocodingApi).AnyContext();
                } catch (Exception ex) {
                    Logger.Error().Exception(ex).Message($"Error occurred looking up reverse geocode: {workItem.Geo}").Write();
                }
            }

            if (location == null)
            {
                return;
            }

            await _cacheClient.SetAsync(workItem.Geo, location, TimeSpan.FromDays(3)).AnyContext();

            var ev = await _eventRepository.GetByIdAsync(workItem.EventId).AnyContext();

            if (ev == null)
            {
                return;
            }

            ev.SetLocation(location);
            await _eventRepository.SaveAsync(ev).AnyContext();
        }
示例#4
0
        public override Task EventBatchProcessingAsync(ICollection <EventContext> contexts)
        {
            var geoGroups = contexts.GroupBy(c => c.Event.Geo);

            var tasks = new List <Task>();

            foreach (var group in geoGroups)
            {
                if (GeoResult.TryParse(group.Key, out var result) && result.IsValid())
                {
                    group.ForEach(c => UpdateGeoAndLocation(c.Event, result, false));
                    continue;
                }

                // The geo coordinates are all the same, set the location from the result of any of the ip addresses.
                if (!String.IsNullOrEmpty(group.Key))
                {
                    var ips = group.SelectMany(c => c.Event.GetIpAddresses()).Union(new[] { group.First().EventPostInfo?.IpAddress }).Distinct().ToList();
                    if (ips.Count > 0)
                    {
                        tasks.Add(UpdateGeoInformationAsync(group, ips));
                    }
                    continue;
                }

                // Each event in the group could be a different user;
                foreach (var context in group)
                {
                    var ips = context.Event.GetIpAddresses().Union(new[] { context.EventPostInfo?.IpAddress }).ToList();
                    if (ips.Count > 0)
                    {
                        tasks.Add(UpdateGeoInformationAsync(context, ips));
                    }
                }
            }

            return(Task.WhenAll(tasks));
        }
示例#5
0
        public async Task <IHttpActionResult> GetSubmitEvent(string projectId = null, int version = 2, string type = null, [UserAgent] string userAgent = null, [QueryStringParameters] IDictionary <string, string[]> parameters = null)
        {
            if (parameters == null || parameters.Count == 0)
            {
                return(StatusCode(HttpStatusCode.OK));
            }

            if (projectId == null)
            {
                projectId = Request.GetDefaultProjectId();
            }

            // must have a project id
            if (String.IsNullOrEmpty(projectId))
            {
                return(BadRequest("No project id specified and no default project was found."));
            }

            var project = await GetProjectAsync(projectId);

            if (project == null)
            {
                return(NotFound());
            }

            // TODO: We could save some overhead if we set the project in the overage handler...
            // Set the project for the configuration response filter.
            Request.SetProject(project);

            string contentEncoding = Request.Content.Headers.ContentEncoding.ToString();
            var    ev = new Event {
                Type = !String.IsNullOrEmpty(type) ? type : Event.KnownTypes.Log
            };

            string identity     = null;
            string identityName = null;

            var exclusions = project.Configuration.Settings.GetStringCollection(SettingsDictionary.KnownKeys.DataExclusions).ToList();

            foreach (var kvp in parameters.Where(p => !String.IsNullOrEmpty(p.Key) && !p.Value.All(String.IsNullOrEmpty)))
            {
                switch (kvp.Key.ToLower())
                {
                case "type":
                    ev.Type = kvp.Value.FirstOrDefault();
                    break;

                case "source":
                    ev.Source = kvp.Value.FirstOrDefault();
                    break;

                case "message":
                    ev.Message = kvp.Value.FirstOrDefault();
                    break;

                case "reference":
                    ev.ReferenceId = kvp.Value.FirstOrDefault();
                    break;

                case "date":
                    DateTimeOffset dtValue;
                    if (DateTimeOffset.TryParse(kvp.Value.FirstOrDefault(), out dtValue))
                    {
                        ev.Date = dtValue;
                    }
                    break;

                case "value":
                    decimal decValue;
                    if (Decimal.TryParse(kvp.Value.FirstOrDefault(), out decValue))
                    {
                        ev.Value = decValue;
                    }
                    break;

                case "geo":
                    GeoResult geo;
                    if (GeoResult.TryParse(kvp.Value.FirstOrDefault(), out geo))
                    {
                        ev.Geo = geo.ToString();
                    }
                    break;

                case "tags":
                    ev.Tags.AddRange(kvp.Value.SelectMany(t => t.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries)).Distinct());
                    break;

                case "identity":
                    identity = kvp.Value.FirstOrDefault();
                    break;

                case "identity.name":
                    identityName = kvp.Value.FirstOrDefault();
                    break;

                default:
                    if (kvp.Key.AnyWildcardMatches(exclusions, true))
                    {
                        continue;
                    }

                    if (kvp.Value.Length > 1)
                    {
                        ev.Data[kvp.Key] = kvp.Value;
                    }
                    else
                    {
                        ev.Data[kvp.Key] = kvp.Value.FirstOrDefault();
                    }

                    break;
                }
            }

            ev.SetUserIdentity(identity, identityName);

            try {
                await _eventPostQueue.EnqueueAsync(new EventPostInfo {
                    MediaType       = Request.Content.Headers.ContentType?.MediaType,
                    CharSet         = Request.Content.Headers.ContentType?.CharSet,
                    ProjectId       = projectId,
                    UserAgent       = userAgent,
                    ApiVersion      = version,
                    Data            = Encoding.UTF8.GetBytes(ev.ToJson(Formatting.None, _jsonSerializerSettings)),
                    ContentEncoding = contentEncoding,
                    IpAddress       = Request.GetClientIpAddress()
                }, _storage);
            } catch (Exception ex) {
                _logger.Error().Exception(ex)
                .Message("Error enqueuing event post.")
                .Project(projectId)
                .Identity(ExceptionlessUser?.EmailAddress)
                .Property("User", ExceptionlessUser)
                .SetActionContext(ActionContext)
                .WriteIf(projectId != Settings.Current.InternalProjectId);

                return(StatusCode(HttpStatusCode.InternalServerError));
            }

            return(StatusCode(HttpStatusCode.OK));
        }