<commit_before>﻿using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Table;
using Microsoft.WindowsAzure.Storage.Table.DataServices;
using System;
using System.Collections;
using System.Linq;

namespace Elmah.AzureTableStorage
{
    /// <summary>
    /// An <see cref="ErrorLog"/> implementation that uses Microsoft Azure 
    /// Storage as its backing store.
    /// </summary>

    public class AzureTableStorageErrorLog : ErrorLog
    {
        private readonly TableServiceContext _tableContext;
        private readonly CloudTable _cloudTable;
        private const string TableName = "Elmah";

        private const int MaxAppNameLength = 60;

        /// <summary>
        /// Initializes a new instance of the <see cref="AzureTableStorageErrorLog"/> class
        /// using a dictionary of configured settings.
        /// </summary>

        public AzureTableStorageErrorLog(IDictionary config)
        {
            if (config == null)
                throw new ArgumentNullException("config");

            var connectionString = ElmahHelper.GetConnectionString(config);

            //
            // If there is no connection string to use then throw an 
            // exception to abort construction.
            //

            if (connectionString.Length == 0)
                throw new ApplicationException("Connection string is missing for the Azure Table Storage error log.");

            var cloudStorageAccount = CloudStorageAccount.Parse(connectionString);
            var tableClient = cloudStorageAccount.CreateCloudTableClient();
            _tableContext = tableClient.GetTableServiceContext();
            _cloudTable = tableClient.GetTableReference(TableName);
            _cloudTable.CreateIfNotExists();

            //
            // Set the application name as this implementation provides
            // per-application isolation over a single store.
            //

            var appName = config.Find("applicationName", string.Empty);

            if (appName.Length > MaxAppNameLength)
            {
                throw new ApplicationException(string.Format(
                    "Application name is too long. Maximum length allowed is {0} characters.",
                    MaxAppNameLength.ToString("N0")));
            }

            ApplicationName = appName;
        }

        /// <summary>
        /// Gets the name of this error log implementation.
        /// </summary>

        public override string Name
        {
            get { return "Microsoft Azure Storage Error Log"; }
        }

        /// <summary>
        /// Logs an error to the database.
        /// </summary>
        /// <remarks>
        /// Use the stored procedure called by this implementation to set a
        /// policy on how long errors are kept in the log. The default
        /// implementation stores all errors for an indefinite time.
        /// </remarks>

        public override string Log(Error error)
        {
            if (error == null)
                throw new ArgumentNullException("error");

            var elmahEntity = new ElmahEntity
            {
                AllXml = ErrorXml.EncodeString(error),
                ApplicationName = error.ApplicationName,
                HostName = error.HostName,
                Message = error.Message,
                Source = error.Source,<commit_msg>correctly log the ApplicationName value<commit_after>﻿using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Table;
using Microsoft.WindowsAzure.Storage.Table.DataServices;
using System;
using System.Collections;
using System.Linq;

namespace Elmah.AzureTableStorage
{
    /// <summary>
    /// An <see cref="ErrorLog"/> implementation that uses Microsoft Azure 
    /// Storage as its backing store.
    /// </summary>

    public class AzureTableStorageErrorLog : ErrorLog
    {
        private readonly TableServiceContext _tableContext;
        private readonly CloudTable _cloudTable;
        private const string TableName = "Elmah";

        private const int MaxAppNameLength = 60;

        /// <summary>
        /// Initializes a new instance of the <see cref="AzureTableStorageErrorLog"/> class
        /// using a dictionary of configured settings.
        /// </summary>

        public AzureTableStorageErrorLog(IDictionary config)
        {
            if (config == null)
                throw new ArgumentNullException("config");

            var connectionString = ElmahHelper.GetConnectionString(config);

            //
            // If there is no connection string to use then throw an 
            // exception to abort construction.
            //

            if (connectionString.Length == 0)
                throw new ApplicationException("Connection string is missing for the Azure Table Storage error log.");

            var cloudStorageAccount = CloudStorageAccount.Parse(connectionString);
            var tableClient = cloudStorageAccount.CreateCloudTableClient();
            _tableContext = tableClient.GetTableServiceContext();
            _cloudTable = tableClient.GetTableReference(TableName);
            _cloudTable.CreateIfNotExists();

            //
            // Set the application name as this implementation provides
            // per-application isolation over a single store.
            //

            var appName = config.Find("applicationName", string.Empty);

            if (appName.Length > MaxAppNameLength)
            {
                throw new ApplicationException(string.Format(
                    "Application name is too long. Maximum length allowed is {0} characters.",
                    MaxAppNameLength.ToString("N0")));
            }

            ApplicationName = appName;
        }

        /// <summary>
        /// Gets the name of this error log implementation.
        /// </summary>

        public override string Name
        {
            get { return "Microsoft Azure Storage Error Log"; }
        }

        /// <summary>
        /// Logs an error to the database.
        /// </summary>
        /// <remarks>
        /// Use the stored procedure called by this implementation to set a
        /// policy on how long errors are kept in the log. The default
        /// implementation stores all errors for an indefinite time.
        /// </remarks>

        public override string Log(Error error)
        {
            if (error == null)
                throw new ArgumentNullException("error");

            var elmahEntity = new ElmahEntity
            {
                AllXml = ErrorXml.EncodeString(error),
                ApplicationName = ApplicationName,
                HostName = error.HostName,
                Message = error.Message,
                Source = error.Source,
{'fraction_non_alphanumeric': 0.08207630878438332, 'fraction_numerical': 0.0014788524105294291, 'mean_word_length': 1.8852389078498293, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4226723', 'n_tokens_mistral': 1543, 'n_tokens_neox': 1476, 'n_words': 497}