I managed to update it for the new SDK syntax.
I also needed a custom json converter for the NameValueCollection type due to a deserialization error I received.
Check out the converter here: NameValueCollection Json Converter
My web.config
<sectionGroup name="couchbaseClients"> <section name="couchbase" type="Couchbase.Configuration.Client.Providers.CouchbaseClientSection, Couchbase.NetClient"/> </sectionGroup> </configSections> <couchbaseClients> <couchbase useSsl="false"> <servers> <add uri="http://localhost:8091/pools"></add> </servers> <buckets> <add name="default" useSsl="false"> <connectionPool name="custom" maxSize="10" minSize="5"></connectionPool> </add> </buckets> </couchbase> </couchbaseClients> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.1" /> </startup> ... <elmah> <errorLog type="MyNameSpace.CouchbaseErrorLog, MyAssembly" couchbaseConfigSection="couchbaseClients/couchbase" /> </elmah>
CouchBaseErrorLog.cs
public class CouchbaseErrorLog : ErrorLog
{
private static ClientConfiguration _client;
private static Cluster _cluster;
private readonly string _elmahBucketName = "default";
/// <summary>
/// Initialize new instance of CouchbaseClient using either default config
/// or specified configuration name
/// </summary>
public CouchbaseErrorLog(IDictionary config)
{
if (config == null)
throw new ArgumentNullException("config");
if (_client == null)
{
if (config.Contains("couchbaseConfigSection"))
{
_client = CreateCouchbaseClient(config["couchbaseConfigSection"] as string);
}
else
{
_client = CreateCouchbaseClient();
}
if (config.Contains("applicationName"))
{
ApplicationName = config["applicationName"] as string;
}
_cluster = new Cluster(_client);
SetNameValueConverter();
//This fixes issue with NameValueCollection deserialization and the serverVaribles property.
}
}
/// <summary>
/// Name displayed in ELMAH viewer
/// </summary>
public override string Name
{
get { return "Couchbase Server Error Log"; }
}
public static ClientConfiguration CreateCouchbaseClient(string couchbaseConfigSection = null)
{
if (couchbaseConfigSection != null)
{
var config = ConfigurationManager.GetSection(couchbaseConfigSection) as CouchbaseClientSection;
if (config == null)
throw new ArgumentException("Couchbase config section " + couchbaseConfigSection + " not found.");
return new ClientConfiguration(config);
}
return new ClientConfiguration();
}
private static void SetNameValueConverter()
{
var settings = new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
TypeNameHandling = TypeNameHandling.All,
Formatting = Formatting.Indented
};
settings.Converters.Add(new NameValueCollectionConverter());
JsonConvert.DefaultSettings = () => settings;
}
/// <summary>
/// Get error log entry by id
/// </summary>
public override ErrorLogEntry GetError(string id)
{
using (var bucket = _cluster.OpenBucket(_client.BucketConfigs[_elmahBucketName].BucketName))
{
return GetError(bucket, id);
}
}
private ErrorLogEntry GetError(IBucket bucket, string id)
{
if (string.IsNullOrEmpty(id))
{
throw new ArgumentNullException("id");
}
try
{
Guid.Parse(id);
}
catch (FormatException e)
{
throw new ArgumentException(e.Message, "id", e);
}
var document = bucket.Get<string>(id);
if (document.Success)
{
var error = JsonConvert.DeserializeObject<Error>(document.Value);
return new ErrorLogEntry(this, id, error);
}
return null;
}
/// <summary>
/// Get list of errors for view in Elmah web viewer
/// </summary>
public override int GetErrors(int pageIndex, int pageSize, IList errorEntryList)
{
if (pageIndex < 0)
throw new ArgumentOutOfRangeException("pageIndex", pageIndex, null);
if (pageSize < 0)
throw new ArgumentOutOfRangeException("pageSize", pageSize, null);
var skip = pageSize*pageIndex;
//this is NOT the most efficient way to page in Couchbase/CouchDB, but is necessary because
//there is no way to keep state of the startkey between requests
//see http://www.couchbase.com/docs/couchbase-manual-2.0/couchbase-views-writing-querying-pagination.html
//for more information
using (var bucket = _cluster.OpenBucket(_client.BucketConfigs[_elmahBucketName].BucketName))
{
var query = bucket.CreateQuery("errors", "by_date", false).Desc().Skip(skip).Limit(pageSize);
var view = bucket.Query<dynamic>(query);
foreach (var item in view.Rows)
{
var errorLogEntry = GetError(bucket, item.Id);
if (errorLogEntry != null)
{
errorEntryList.Add(errorLogEntry);
}
}
return view.Rows.Count();
}
}
/// <summary>
/// Log an error
/// </summary>
public override string Log(Error error)
{
if (error == null)
throw new ArgumentNullException("error");
var id = Guid.NewGuid().ToString();
using (var bucket = _cluster.OpenBucket(_client.BucketConfigs[_elmahBucketName].BucketName))
{
// var errorJson = JsonConvert.SerializeObject(error);
var errorJson = JsonConvert.SerializeObject(error);
var result = bucket.Insert(id, errorJson);
#if DEBUG
if (!result.Success && Debugger.IsAttached)
{
Debugger.Break();
}
#endif
}
return id;
}
}
ViewOne last thing, I need to modify the couchbase view.
//view code for Elmah viewer. Must be named "by_date" and located in design document named "errors" without the quotes.
function (doc) {
if (doc.exception) {
emit(doc.time, null);
}
}
No comments:
Post a Comment