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); } } }
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); }
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(); }
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)); }
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)); }