Пример #1
0
        /// <summary>
        /// Generate the JavaScript to create a logger.
        /// </summary>
        /// <param name="loggerVariableName">
        /// New logger object will be assigned to this JS variable.
        /// </param>
        /// <param name="loggerName">
        /// Name of the logger. Could be null (for the root logger).
        /// </param>
        /// <param name="sb">
        /// JS code will be appended to this.
        /// </param>
        public static void GenerateLogger(string loggerVariableName, string loggerName, StringBuilder sb)
        {
            string quotedLoggerName =
                loggerName == null ? "" : @"""" + loggerName + @"""";

            JavaScriptHelpers.WriteLine(string.Format("var {0}=JL({1});", loggerVariableName, quotedLoggerName), sb);
        }
Пример #2
0
        /// <summary>
        /// Generates the JavaScript for the call to setOptions to set the options for an object
        /// (the JL object itself, an appender or a logger).
        /// </summary>
        /// <param name="parentName">
        /// JavaScript variable that holds the element.
        /// </param>
        /// <param name="xe">
        /// XML element. The attributes on this element will provide the values for the options.
        /// </param>
        /// <param name="attributeInfos">
        /// Describes which attributes to use as options and how to validate them.
        ///
        /// As regards attributeInfos that have a SubTagName:
        /// * The value of such an attribute is an array, for example [ 'a', 'b' ]
        /// * If there are no child elements with the given sub tag name, there is no value, and no entry for that attributeinfo in
        ///   the generated setOption.
        /// * If there is only one child element and it does not have an attribute, the value is an empty array [].
        /// </param>
        /// <param name="initialAttributeValues">
        /// Initial attribute values. The elements found in xe will be added to this.
        /// If null, this method will create an empty collection itself.
        /// </param>
        /// <param name="sb">
        /// The JS code is added to this.
        /// </param>
        /// <param name="validate">
        /// If not null, this method is called on the generated attribute values. This can be used to throw an exception
        /// if the given parameters are not valid.
        /// </param>
        public static void ProcessOptionAttributes(string parentName, XmlElement xe, IEnumerable <AttributeInfo> attributeInfos,
                                                   AttributeValueCollection initialAttributeValues, StringBuilder sb,
                                                   Action <AttributeValueCollection> validate = null)
        {
            var attributeValues = initialAttributeValues ?? new AttributeValueCollection();

            XmlHelpers.ProcessAttributes(xe, attributeInfos, attributeValues);

            if (validate != null)
            {
                validate(attributeValues);
            }

            JavaScriptHelpers.GenerateSetOptions(parentName, attributeValues, sb);
        }
Пример #3
0
        // 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(XmlElement xe, StringBuilder sb, Func <string, string> virtualToAbsoluteFunc, string userIp, string requestId, bool generateClosure)
        {
            string loggerProductionLibraryVirtualPath = XmlHelpers.OptionalAttribute(xe, "productionLibraryPath", "");
            bool   loggerEnabled = bool.Parse(XmlHelpers.OptionalAttribute(xe, "enabled", "true", Constants.RegexBool));

            string loggerProductionLibraryPath = null;

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

            if (!loggerEnabled)
            {
                if (!string.IsNullOrWhiteSpace(loggerProductionLibraryPath))
                {
                    JavaScriptHelpers.WriteScriptTag(loggerProductionLibraryPath, sb);
                }

                JavaScriptHelpers.WriteJavaScriptBeginTag(sb);
                Utils.ProcessOptionAttributes(Constants.JsLogObjectName, xe, Constants.JSNLogAttributes, null, sb);
                JavaScriptHelpers.WriteJavaScriptEndTag(sb);

                return;
            }

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

            // Generate setOptions for JSNLog object itself

            AttributeValueCollection attributeValues = new AttributeValueCollection();

            attributeValues[Constants.JsLogObjectClientIpOption]  = new Value(userIp, new StringValue());
            attributeValues[Constants.JsLogObjectRequestIdOption] = new Value(requestId, new StringValue());

            // Set default value for defaultAjaxUrl attribute
            attributeValues[Constants.JsLogObjectDefaultAjaxUrlOption] =
                new Value(virtualToAbsoluteFunc(Constants.DefaultDefaultAjaxUrl), new StringValue());

            Utils.ProcessOptionAttributes(Constants.JsLogObjectName, xe, Constants.JSNLogAttributes,
                                          attributeValues, sb);

            // Process all loggers and appenders

            Dictionary <string, string> appenderNames = new Dictionary <string, string>();
            Sequence sequence = new Sequence();

            // -----------------
            // First process all assembly tags

            topLeveltagInfos =
                new List <XmlHelpers.TagInfo>(
                    new[] {
                new XmlHelpers.TagInfo(Constants.TagAssembly, ProcessAssembly, Constants.AssemblyAttributes, (int)Constants.OrderNbr.Assembly)
            });

            XmlHelpers.ProcessNodeList(
                xe.ChildNodes,
                topLeveltagInfos.Where(t => t.Tag == Constants.TagAssembly).ToList(),
                null, appenderNames, sequence, sb,
                string.Format("^{0}*", Constants.TagAssembly));

            // -----------------
            // The elements (if any) from external assemblies have now been loaded (with the assembly elements).
            // Now add the elements from the executing assembly after the external ones.
            // This way, logger elements are processed last - after any new appenders.

            AddAssemblyTagInfos(Assembly.GetExecutingAssembly());

            // Now process the external and internal elements, but not the assembly elements.

            XmlHelpers.ProcessNodeList(
                xe.ChildNodes,
                topLeveltagInfos,
                null, appenderNames, sequence, sb,
                string.Format("^((?!{0}).)*$", Constants.TagAssembly));

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

            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);
            }
        }
Пример #4
0
 /// <summary>
 /// Generates the JavaScript create an object.
 /// </summary>
 /// <param name="objectVariableName"></param>
 /// <param name="createMethodName"></param>
 /// <param name="name">
 /// Name of the object as known to the user. For example the appender name.
 /// </param>
 /// <param name="sb"></param>
 public static void GenerateCreate(string objectVariableName, string createMethodName, string name, StringBuilder sb)
 {
     JavaScriptHelpers.WriteLine(string.Format("var {0}=JL.{1}('{2}');", objectVariableName, createMethodName, name), sb);
 }
Пример #5
0
        // 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);
            }
        }