コード例 #1
0
        public ActionResult RequestIdTest(string id)
        {
            ViewBag.RequestId         = JavascriptLogging.RequestId();
            ViewBag.PassedInRequestId = id;

            return(View());
        }
コード例 #2
0
        public void IsLoggingUrl_NoUrlsConfigured_CodeConfig()
        {
            JavascriptLogging.SetJsnlogConfiguration(null, null);

            Assert.True(LoggingUrlHelpers.IsLoggingUrl("/jsnlog.logger"));
            Assert.True(LoggingUrlHelpers.IsLoggingUrl("http://abc.com/jsnlog.logger"));
            Assert.False(LoggingUrlHelpers.IsLoggingUrl("http://abc.com/jsnlog.css"));
        }
コード例 #3
0
        public static void SetConfigCache(string configXml, ILoggingAdapter logger = null)
        {
            // Set config cache in JavascriptLogging to contents of xe
            XmlElement xe = ConfigToXe(configXml);

            JavascriptLogging.SetJsnlogConfiguration(null, logger);
            JavascriptLogging.GetJsnlogConfiguration(() => xe);
        }
コード例 #4
0
        protected void Application_BeginRequest()
        {
            // Configure CORS.

            JavascriptLogging.SetJsnlogConfiguration(new JsnlogConfiguration
            {
                defaultAjaxUrl          = "http://apicorslocalhost.local/jsnlog.logger",
                corsAllowedOriginsRegex = @"^https?:\/\/([a-z0-9]+[.])*corslocalhost[.]local$",
                productionLibraryPath   = "~/Scripts/jsnlog.min.js"
            });
        }
コード例 #5
0
        /// <summary>
        /// Processes the incoming request. This method is not depended on the environment and so can be unit tested.
        /// Note that the incoming request may not be the POST request with log data.
        ///
        /// Effect of this method:
        /// * setting StatusCode on the response parameter
        /// * adding headers to the response parameter
        /// * logging contents of log request
        /// </summary>
        /// <param name="json">
        /// JSON payload in the incoming request
        /// </param>
        /// <param name="logRequestBase">
        /// * Type of browser that sent the request
        /// * IP address that sent the address
        /// * Url that the request was sent to
        /// * Request Id sent as part of the request
        /// * Request data to be given to onLogging event handler
        /// </param>
        /// <param name="serverSideTimeUtc">Current time in UTC</param>
        /// <param name="httpMethod">HTTP method of the request</param>
        /// <param name="origin">Value of the Origin request header</param>
        /// <param name="response">
        /// Empty response object. This method can add headers, etc.
        /// </param>
        internal static void ProcessLogRequest(string json, LogRequestBase logRequestBase,
                                               DateTime serverSideTimeUtc,
                                               string httpMethod, string origin, LogResponse response)
        {
            JsnlogConfiguration jsnlogConfiguration = JavascriptLogging.GetJsnlogConfiguration();

            ILoggingAdapter logger = JavascriptLogging.GetLogger();

            if ((httpMethod != "POST") && (httpMethod != "OPTIONS"))
            {
                response.StatusCode = (int)HttpStatusCode.MethodNotAllowed;
                return;
            }

            string corsAllowedOriginsRegex = jsnlogConfiguration.corsAllowedOriginsRegex;
            bool   originIsAllowed         = ((!string.IsNullOrEmpty(corsAllowedOriginsRegex)) && (!string.IsNullOrEmpty(origin)) && Regex.IsMatch(origin, corsAllowedOriginsRegex));

            if (originIsAllowed)
            {
                response.AppendHeader("Access-Control-Allow-Origin", origin);
            }

            response.StatusCode = (int)HttpStatusCode.OK;

            if (httpMethod == "OPTIONS")
            {
                // Standard HTTP response (not related to CORS)
                response.AppendHeader("Allow", "POST");

                // Only if the origin is allowed send CORS headers
                if (originIsAllowed)
                {
                    response.AppendHeader("Access-Control-Max-Age", Constants.CorsAccessControlMaxAgeInSeconds.ToString());
                    response.AppendHeader("Access-Control-Allow-Methods", "POST");
                    response.AppendHeader("Access-Control-Allow-Headers", "jsnlog-requestid, content-type");
                }

                return;
            }

            // httpMethod must be POST

            List <FinalLogData> logDatas =
                ProcessLogRequestExec(json, logRequestBase, serverSideTimeUtc, jsnlogConfiguration);

            // ---------------------------------
            // Pass log data to Common Logging

            foreach (FinalLogData logData in logDatas)
            {
                logger.Log(logData);
            }
        }
コード例 #6
0
        public void SetConfigWithJsnlogInWebConfig()
        {
            // Arrange

            string configXml = @"
                <jsnlog maxMessages=""5"">
</jsnlog>
";

            XmlElement          xe = CommonTestHelpers.ConfigToXe(configXml);
            JsnlogConfiguration jsnlogConfiguration = new JsnlogConfiguration();

            // Act

            Exception ex = Assert.Throws <ConflictingConfigException>(() => JavascriptLogging.SetJsnlogConfiguration(() => xe, jsnlogConfiguration));
        }
コード例 #7
0
        protected void Application_BeginRequest()
        {
            // Use configuration in code instead of configuration in web.config/.

            JavascriptLogging.SetJsnlogConfiguration(new JsnlogConfiguration
            {
                serverSideMessageFormat = "%userHostAddress, %logger, %level, %message",
                productionLibraryPath   = "~/Scripts/jsnlog.min.js",
                loggers = new List <Logger>
                {
                    new Logger
                    {
                        name  = "jsLogger",
                        level = "FATAL"
                    }
                }
            });
        }
コード例 #8
0
        public void SetConfigWithoutJsnlogInWebConfig()
        {
            // Arrange

            JsnlogConfiguration jsnlogConfiguration = new JsnlogConfiguration
            {
                maxMessages = 5
            };

            JavascriptLogging.SetJsnlogConfiguration(() => null, jsnlogConfiguration);

            // Act

            JsnlogConfiguration retrievedJsnlogConfiguration = JavascriptLogging.GetJsnlogConfiguration();

            // Assert

            // Retrieved object is expected to be the exact same object that was put in
            Assert.Equal(jsnlogConfiguration, retrievedJsnlogConfiguration);
            Assert.Equal(jsnlogConfiguration.maxMessages, retrievedJsnlogConfiguration.maxMessages);
        }
コード例 #9
0
        public void GetConfigFromWebConfig()
        {
            // Arrange

            string     configXml = @"
                <jsnlog maxMessages=""5"">
</jsnlog>
";
            XmlElement xe        = CommonTestHelpers.ConfigToXe(configXml);

            JavascriptLogging.SetJsnlogConfiguration(null);
            JavascriptLogging.GetJsnlogConfiguration(() => xe);

            // Act

            JsnlogConfiguration retrievedJsnlogConfiguration = JavascriptLogging.GetJsnlogConfiguration();

            // Assert

            // Retrieved object is expected to be the exact same object that was put in
            Assert.Equal((uint)5, retrievedJsnlogConfiguration.maxMessages);
        }
コード例 #10
0
ファイル: LoggingUrlHelpers.cs プロジェクト: dazinator/jsnlog
        /// <summary>
        /// Returns true if a request with the given url is a logging request that should be handled
        /// by JSNLog.
        ///
        /// Note that the user may have set the defaultUrl or an appender url because they want to use
        /// the standard url /jsnlog.logger for something else. So you don't want to always allow
        /// /jsnlog.logger.
        ///
        /// On the other hand, it is impossible to figure out exactly what urls the user has used, because you
        /// don't know which loggers are being used in the user's code.
        /// So you can't only match against the urls specified with the appenders.
        ///
        /// So this method assumes that in addition to the appenders that have been configured,
        /// the default appender is also used. That is, it also passes the defaultUrl set by the user
        /// (and if that is not set, the defaultDefaultUrl).
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public static bool IsLoggingUrl(string url)
        {
            if (string.IsNullOrEmpty(url))
            {
                throw new ArgumentNullException(url);
            }

            JsnlogConfiguration jsnlogConfiguration = JavascriptLogging.GetJsnlogConfiguration();

            if (jsnlogConfiguration == null)
            {
                return(UrlMatchesAppenderUrl(Constants.DefaultDefaultAjaxUrl, url));
            }

            string resolvedDefaultUrl = ResolvedAppenderUrl(Constants.DefaultDefaultAjaxUrl, jsnlogConfiguration.defaultAjaxUrl, null);

            if (UrlMatchesAppenderUrl(resolvedDefaultUrl, url))
            {
                return(true);
            }

            if (jsnlogConfiguration.ajaxAppenders != null)
            {
                foreach (AjaxAppender ajaxAppender in jsnlogConfiguration.ajaxAppenders)
                {
                    string resolvedAppenderUrl = ResolvedAppenderUrl(
                        Constants.DefaultDefaultAjaxUrl, jsnlogConfiguration.defaultAjaxUrl, ajaxAppender.url);
                    if (UrlMatchesAppenderUrl(resolvedAppenderUrl, url))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
コード例 #11
0
        private void LoggingHandler(LoggingEventArgs e)
        {
            var currReqId = JavascriptLogging.RequestId();

            e.FinalMessage = String.Format("[{0,-36}] {1}", currReqId, e.FinalMessage);
        }
コード例 #12
0
ファイル: ConfigProcessor.cs プロジェクト: dazinator/jsnlog
        // This version is not reliant on sitting in a web site, so can be unit tested.
        // generateClosure - if false, no function closure is generated around the generated JS code. Only set to false when unit testing.
        // Doing this assumes that jsnlog.js has loaded before the code generated by the method is executed.
        //
        // You want to set this to false during unit testing, because then you need direct access outside the closure of variables
        // that are private to the closure, specifically dummyappenders that store the log messages you receive, so you can unit test them.
        public void ProcessRootExec(StringBuilder sb, Func <string, string> virtualToAbsoluteFunc,
                                    string userIp, string requestId, bool generateClosure)
        {
            Dictionary <string, string> appenderNames       = new Dictionary <string, string>();
            JsnlogConfiguration         jsnlogConfiguration = JavascriptLogging.GetJsnlogConfiguration();

            string loggerProductionLibraryVirtualPath = jsnlogConfiguration.productionLibraryPath;
            bool   loggerEnabled = jsnlogConfiguration.enabled;

            string loggerProductionLibraryPath = null;

            if (!string.IsNullOrEmpty(loggerProductionLibraryVirtualPath))
            {
                // Every hard coded path must be resolved. See the declaration of DefaultDefaultAjaxUrl
                loggerProductionLibraryPath = Utils.AbsoluteUrl(loggerProductionLibraryVirtualPath, virtualToAbsoluteFunc);
            }

            JavaScriptHelpers.WriteJavaScriptBeginTag(sb);
            if (generateClosure)
            {
                JavaScriptHelpers.WriteLine(string.Format("var {0} = function ({1}) {{", Constants.GlobalMethodCalledAfterJsnlogJsLoaded, Constants.JsLogObjectName), sb);
            }

            // Generate setOptions for JSNLog object itself

            var jsonFields = new List <string>();

            JavaScriptHelpers.AddJsonField(jsonFields, Constants.JsLogObjectClientIpOption, userIp, new StringValue());
            JavaScriptHelpers.AddJsonField(jsonFields, Constants.JsLogObjectRequestIdOption, requestId, new StringValue());

            JavaScriptHelpers.GenerateSetOptions(Constants.JsLogObjectName, jsnlogConfiguration,
                                                 appenderNames, virtualToAbsoluteFunc, sb, jsonFields);

            if (loggerEnabled)
            {
                // Process all loggers and appenders. First process the appenders, because the loggers can be
                // dependent on the appenders, and will use appenderNames to translate configuration appender names
                // to JavaScript names.

                int sequence = 0;

                GenerateCreateJavaScript(jsnlogConfiguration.ajaxAppenders, sb, virtualToAbsoluteFunc, appenderNames, ref sequence);
                GenerateCreateJavaScript(jsnlogConfiguration.consoleAppenders, sb, virtualToAbsoluteFunc, appenderNames, ref sequence);
                GenerateCreateJavaScript(jsnlogConfiguration.loggers, sb, virtualToAbsoluteFunc, appenderNames, ref sequence);
            }

            // -------------

            if (generateClosure)
            {
                // Generate code to execute the function, in case jsnlog.js has already been loaded.
                // Wrap in try catch, so if jsnlog.js hasn't been loaded, the resulting exception will be swallowed.
                JavaScriptHelpers.WriteLine(string.Format("}}; try {{ {0}({1}); }} catch(e) {{}};", Constants.GlobalMethodCalledAfterJsnlogJsLoaded, Constants.JsLogObjectName), sb);
            }
            JavaScriptHelpers.WriteJavaScriptEndTag(sb);

            // Write the script tag that loads jsnlog.js after the code generated from the web.config.
            // When using jsnlog.js as an AMD module or in a bundle, jsnlog.js will be loaded after that code as well,
            // and creating a similar situation in the default out of the box loading option makes it more likely
            // you pick up bugs during testing.
            if (!string.IsNullOrWhiteSpace(loggerProductionLibraryPath))
            {
                JavaScriptHelpers.WriteScriptTag(loggerProductionLibraryPath, sb);
            }
        }
コード例 #13
0
        private static FinalLogData ProcessLogItem(LogRequestSingleMsg logItem, LogRequestBase logRequestBase,
                                                   DateTime serverSideTimeUtc, JsnlogConfiguration jsnlogConfiguration)
        {
            string serversideLoggerNameOverride = jsnlogConfiguration.serverSideLogger;
            string messageFormat = jsnlogConfiguration.serverSideMessageFormat;
            string levelOverride = jsnlogConfiguration.serverSideLevel;
            string dateFormat    = jsnlogConfiguration.dateFormat;

            try
            {
                LevelUtils.ValidateLevel(levelOverride);
            }
            catch (Exception e)
            {
                throw new PropertyException("levelOverride", e);
            }

            // ----------------

            string message = logItem.m;
            string logger  = logItem.n;
            string level   = logItem.l; // note that level as sent by the javascript is a number
            string entryId = logItem.u;

            DateTime utcDate     = DateTime.UtcNow;
            string   timestampMs = logItem.t;

            try
            {
                double ms = double.Parse(timestampMs);
                utcDate = DateTime.SpecifyKind((new DateTime(1970, 1, 1)).AddMilliseconds(ms), DateTimeKind.Utc);
            }
            catch
            {
            }

            // ----------------

            string jsonmessage = "";

            if (messageFormat.Contains("%jsonmessage"))
            {
                jsonmessage = LogMessageHelpers.EnsureValidJson(message);
            }

            // ----------------

            var logRequest       = new LogRequest(message, logger, level, utcDate, entryId, jsonmessage, logRequestBase);
            var loggingEventArgs = new LoggingEventArgs(logRequest)
            {
                Cancel = false,
                ServerSideMessageFormat = messageFormat
            };

            // ----------------

            if (string.IsNullOrWhiteSpace(logger))
            {
                logger = Constants.RootLoggerNameServerSide;
            }
            loggingEventArgs.FinalLogger = serversideLoggerNameOverride ?? logger;

            string consolidatedLevel = levelOverride ?? level;

            loggingEventArgs.FinalLevel = LevelUtils.ParseLevel(consolidatedLevel).Value;

            // ----------------

            loggingEventArgs.FinalMessage = messageFormat
                                            .Replace("%message", message)
                                            .Replace("%entryId", entryId)
                                            .Replace("%jsonmessage", jsonmessage)
                                            .Replace("%utcDateServer", serverSideTimeUtc.ToString(dateFormat))
                                            .Replace("%utcDate", utcDate.ToString(dateFormat))
                                            .Replace("%dateServer", Utils.UtcToLocalDateTime(serverSideTimeUtc).ToString(dateFormat))
                                            .Replace("%date", Utils.UtcToLocalDateTime(utcDate).ToString(dateFormat))
                                            .Replace("%level", level)
                                            .Replace("%newline", System.Environment.NewLine)
                                            .Replace("%userAgent", logRequestBase.UserAgent)
                                            .Replace("%userHostAddress", logRequestBase.UserHostAddress)
                                            .Replace("%requestId", logRequestBase.RequestId ?? "")
                                            .Replace("%url", logRequestBase.Url)
                                            .Replace("%logger", logger);

            // ----------------

            JavascriptLogging.RaiseLoggingEvent(loggingEventArgs);

            // If user wrote event handler that decided not to log the message, return null
            if (loggingEventArgs.Cancel)
            {
                return(null);
            }

            return(loggingEventArgs);
        }
コード例 #14
0
 private void RunTest(JsnlogConfiguration jsnlogConfiguration)
 {
     JavascriptLogging.SetJsnlogConfiguration(() => null, jsnlogConfiguration);
     JsnlogConfiguration retrievedJsnlogConfiguration = JavascriptLogging.GetJsnlogConfiguration();
 }