public List <T> GetStats <T>() where T : StatsBase { var output = new List <T>(); if (this.mongo == null) { throw new Exception("Stats module failure"); } //use a 'complete' object so year gets assigned T s = new RequestStatsComplete(null, null).OutputAs <T>(); if (string.IsNullOrEmpty(s.GetCollectionName())) { throw new ArgumentException("Invalid stats type"); } //since got here it should be ok to proceed //this will pull all the s***e off the specified collection var cursor = this.mongocollections[s.GetCollectionName()].FindAs <T>(s.GetReadQueryBuilder()); cursor.SetSortOrder(MongoDB.Driver.Builders.SortBy.Descending("Bytes")); //cursor.SetLimit(100); return(cursor.ToList <T>()); }
/// <summary> /// saves the stats /// </summary> private void SaveStatsInternal(string referrer, string hostAddress, bool cache, long bytes) { //make sure mongo client is available, otherwise will not be able to do the saving if (this.mongo == null) { return; } //if referrer is unknown, just dump the referrer stats as unknown if (string.IsNullOrEmpty(referrer)) { referrer = "unknown"; } //prepare the request stats object var rs = new RequestStatsComplete(referrer, hostAddress, cache, bytes); //get the ip related geo data try { if (this.geoIpCache.ContainsKey(hostAddress)) { rs.SetGeoIp(this.geoIpCache[hostAddress]); } else { if (this.geoIpReader != null) { var gip = this.geoIpReader.City(hostAddress); this.geoIpCache[hostAddress] = gip; rs.SetGeoIp(gip); } } } catch (MaxMind.GeoIP2.Exceptions.AddressNotFoundException) { //address not in the db so screw it //db rec will not have geo ip related data } catch (Exception ex) { HandleGeoIpException(ex); } List <StatsBase> stats = new List <StatsBase>(); //always save the totalstats stats.Add(rs.OutputAs <ReferrerStatsTotal>()); stats.Add(rs.OutputAs <IpStatsTotal>()); //yearly stats if (this.settings.LogYearlyStats) { stats.Add(rs.OutputAs <ReferrerStatsYearly>()); stats.Add(rs.OutputAs <IpStatsYearly>()); } //monthly stats if (this.settings.LogMonthlyStats) { stats.Add(rs.OutputAs <ReferrerStatsMonthly>()); stats.Add(rs.OutputAs <IpStatsMonthly>()); } //weekly stats if (this.settings.LogWeeklyStats) { stats.Add(rs.OutputAs <ReferrerStatsWeekly>()); stats.Add(rs.OutputAs <IpStatsWeekly>()); } //daily stats if (this.settings.LogDailyStats) { stats.Add(rs.OutputAs <ReferrerStatsDaily>()); stats.Add(rs.OutputAs <IpStatsDaily>()); } //finally save whatever should be saved //Note: //it looks like sometimes 2 or more inserts with the same unique key may //be issued simultanously. //Because of that, before logging out the exception, try to perform the operation again // //also now a try/catch block is created for each op, //so one failure does not prevent the other saves. foreach (var s in stats) { var action = (Action)(() => { this.mongocollections[s.GetCollectionName()].Update( s.GetQueryBuilder(), s.GetUpdateBuilder(), MongoDB.Driver.UpdateFlags.Upsert ); }); try { action(); } catch { try { action(); } catch (Exception ex) { HandleMongoDbException(ex); } } } }