npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

canadarm

v1.0.2

Published

A JavaScript logger that works for you!

Downloads

35

Readme

canadarm

Build Status Code Climate

Canadarm makes JavaScript logging easy and seamless, helping you figure out what went wrong with your scripts. Named for the Canadarm we hope this too helps you piece together log information to figure out what went wrong with your scripts.

If you have any ideas or questions reach out to us on our Google group.

Installing Canadarm

Canadarm can be installed in the following ways:

  • Use one of the files located in the build folder.

  • Use npm:

    npm install canadarm

  • Reference a hosted version provided by jsdelivr:

    https://cdn.jsdelivr.net/canadarm/1.0.1/canadarm.min.js

Using canadarm

Interaction with canadarm is via the Canadarm object. Log appenders in Canadarm.Appender are used to gather the log information. Log handlers in Canadarm.Handler are used to send the log information. Note, IE 8 and above are the only IE versions this library actively supports. Use jQuery in IE 8 for automatic event handling. This library shims addEventListener so events are automatically wrapped. For more information on IE 8 see the bottom of this readme.

Suggested Configuration

In general you should be able to use the following configuration for normal web applications. If your JavaScript executes in an environment that is not under its control it is recommended to make use of the Canadarm.localWatch and Canadarm.localAttempt.

Canadarm.init({
  onError: true,  // Set to false if you do not want window.onerror set.
  wrapEvents: true, // Set to false if you do not want all event handlers to be logged for errors
  logLevel: Canadarm.level.WARN, // Will only send logs for level of WARN and above.
  appenders: [
    Canadarm.Appender.standardLogAppender
  ],
  handlers: [
    Canadarm.Handler.beaconLogHandler('http://example.com/beacon.gif'),
    Canadarm.Handler.consoleLogHandler
  ]
});

There are some scenarios where you will want to watch a specific function differently than the rest. For example, let's say you want to use a different Handler or Appender for one special function. You should use the Canadarm.localWatch function to modify how the special function is monitored.

Settings

These are passed to Canadarm.init and may be passed to the custom logging mentioned below. Settings must be passed into the Canadarm.init call. There are no default values.

| Field | Meaning | |------------|--------------------------------------------------------------------------------------------------------------------------------------------| | onError | Set to true if the window.onerror should be overridden. If a window.onerror is already defined it will be called as well as canadarm. | | wrapEvents | Set to true to wrap all event bound functions. | | logLevel | The log level to stop sending logs for. It will send logs for the level passed and above. If not defined will log everything. | | appenders | A list of appenders to use. See the Appenders section. | | handlers | A list of handlers to use. See the Handlers section. |

Local Usage

You do have the option of using Canadarm.localWatch. This method is useful if you have a specific function you want to check on and have special configuration for. For example, if you are one of many libraries on a page (and want to use this library) using the Canadarm.localWatch helps you play nice with your neighbors. Here is an example of this should be used in conjunction with other libraries (note, you will impact them with the call to Canadarm.init).

// Canadarm.init call (for all libraries/parts of the page)
Canadarm.init({
  onError: false,
  wrapEvents: false,
  logLevel: Canadarm.level.WARN // Will only send logs for level of WARN and above.
})

Then when you want to watch your specific function you can do something similar according to the code below. Here is the method signature for Canadarm.localWatch and Canadarm.localAttempt:

| Parameter | Description | |-----------|-------------------------------------------------------------------------------------------------------------------------| | fn | The function to watch for errors | | settings | A settings object that overrides the appenders and/or handlers that are provided to Canadarm.init when passed in | | context | The context to execute at, defaults to this. You normally will not set this value |

mySpecificFunction = Canadarm.localWatch(function () {
    // The parts that do the actual work of your application.
  },
  {
    appenders: [Canadarm.Appender.standardLogAppender],
    handlers: [Canadarm.Handler.beaconHandler('http://example.com/more-path/')]
  }
)

Below are the available local usage functions within Canadarm. Canadarm.watch and Canadarm.attempt are dependent on all settings passed to Canadarm.init. The local versions Canadarm.localWatch and Canadarm.localAttempt allow for more fine grained control. See section above.

| Function | Usage | |-------------------------|---------------------------------------------------------------------------------------------| | Canadarm.watch | All future calls to this function will be logged if an error occurs | | Canadarm.attempt | Use this to immediately invoke the function and log an error | | Canadarm.localWatch | Same as Canadarm.watch, but allows passing settings and contextas defined above. | | Canadarm.localAttempt | Same as Canadarm.attempt, but allows passing settings and context as defined above. |

Appender

Appenders are functions that return a dictionary of log information. This information is then passed to the Handlers. For example below is a possible platform.js:

function platformLogAppender() {
  var platform = window.navigator.platform || Canadarm.constant.UNKNOWN_LOG,
    language = window.navigator.language || Canadarm.constant.UNKNOWN_LOG,
    vendor = window.navigator.vendor || Canadarm.constant.UNKNOWN_LOG;

  return {
    platform : platform,
    language : language,
    vendor   : vendor
  };
}

The signature passed to an appender is: level, exception, message, data.

There are some default appenders: Canadarm.Appender.standardLogAppender. For now see their method signatures in the lib/appender folder for what they log.

To add an appender do the following:

Canadarm.addAppender(Canadarm.Appender.standardLogAppender);

standardLogAppender

The standard log appender returns the following: (all values default to '?' when they cannot be determined)

| Field | Meaning | |--------------|----------------------------------------------------| | characterSet | Encoding used to read the page | | columnNumber | Column number of error | | language | The language set on the page | | lineNumber | Line number of the error | | logDate | Date of the log for what the browser thinks is UTC | | msg | The message of the error | | pageURL | URL the error occurred at | | stack | stack trace for the error | | type | Right now will always be 'jserror' | | scriptURL | URL of the script that threw the error |

Handler

Handlers are functions that handle logs. Canadarm provides two built-in handlers:

  • Canadarm.Handler.beaconLogHandler: Sends the log to a configured URL endpoint.
  • Canadarm.Handler.consoleLogHandler: Sends the log to the JavaScript console.

A handler takes a single object for its signature: logAttributes which is a standard JavaScript object with key value pairs.

To add a handler do the following:

Canadarm.addHandler(Canadarm.Handler.consoleLogHandler);
Canadarm.addHandler(Canadarm.Handler.beaconLogHandler('http://example.com/beacon.gif'));

Console Log Handler

This handler will output all calls to the console. It simply makes a call to console.error.

Beacon Log Handler

This handler will make a GET call to the provided URL. We recommend the end point given use an access_combined log format.

Custom Error Logging

If you need to log an error for information yourself you can do this using each of the following:

  • Canadarm.debug
  • Canadarm.info
  • Canadarm.warn
  • Canadarm.error
  • Canadarm.fatal

The signature for custom logging: (message, exception, data, settings)

| Parameters | Meaning | |------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | message | This will be the message of your custom error | | exception | This must be an Error object, likely gotten from a try/catch | | data | This is an object you can pass extra data for your log. If you wanted to add color you could pass {color: 'red'} and it would be added to the log the same as Appenders work. | | settings | These settings allow you to pass in different handlers and appenders. This can be useful if you do not want to use the globally defined settings passed to Canadarm.init |

Development

When developing against this repository it may be worth looking at the docs folder. You can see the auto generated documentation by running a simple file server in the docs folder. For example if you have Python 2.7.x you can run python -m SimpleHTTPServer and see the documentation served. You will see the documentation running at http://localhost:8000/ by default.

Running the project

There is an example directory that contains code to functionally validate any changes. To see these files follow the steps below.

  1. git clone
  2. cd canadarm
  3. npm install
  4. cd example
  5. python -m SimpleHTTPServer Assumes Python 2.7.x use python -m http.server for Python 3.x.y
  6. Go to your localhost:8000/html

Once you're at the localhost:8000/html open the console and you'll see the current attempt at parsing out log info.

There are two pages. The index.html which shows up by default and the local.html. index.html had the default recommended setup of canadarm. The local.html does not do any of the automatic event watching. This is helpful for making sure changes still work with the Canadarm.localWatch and Canadarm.localAttempt functions.

Testing

Canadarm uses the mocha testing framework. To run the tests just run: grunt build while in the root directory of the application. This will run all of our tests. Example:

grunt build

Running "jshint:all" (jshint) task
>> 10 files lint free.

Running "jshint:concat" (jshint) task
>> 1 file lint free.

Running "concat:canadarm" (concat) task
File "build/canadarm.js" created.
File "example/js/canadarm.js" created.

Running "jshint:concat" (jshint) task
>> 1 file lint free.

Running "uglify:candarm" (uglify) task
File "build/canadarm.min.js" created.

Running "mochaTest:test" (mochaTest) task
[ 'one=one\n', 'two=two\n' ]
 14  -_-_-_-_-_-_-_-_,------,
 0   -_-_-_-_-_-_-_-_|   /\_/\
 0   -_-_-_-_-_-_-_-^|__( ^ .^)
     -_-_-_-_-_-_-_-  ""  ""

  14 passing (28ms)


Done, without errors.

Helpers

There are a few grunt tasks that do things to help out with development.

grunt jshint -- this lints the project showing any errors that have occurred

grunt build -- this will lint the project and create the build file. It also puts the built file into the example project.

Internet Explorer 8

Event handling

If you set wrapEvents to true, in Internet Explorer 8 only events that are added via addEventListener will be automatically watched. Meaning if a call is directly made to attachEvent you must wrap the event handler in a Canadarm.watch to have the errors managed by canadarm. jQuery uses addEventListener if it exists on the object when an event is bound. Canadarm will shim addEventListener and removeEventListener by following the shim found here. This means that events will only be automatically monitored if canadarm is initialized before all other JavaScript event binding occurs. For this reason you may need to include the Canadarm init call in your <head> or the very first thing in your JavaScript that's loaded after your DOM is ready.

This is all necessary because there is a defect in IE 8 around how attachEvent works for XML defined nodes of the form <foo:bar>. These nodes do not honor the prototype chain properly for Element.prototype.attachEvent. Therefore, we cannot simply wrap Element.prototype.attachEvent like we do for EventTarget.prototype.addEventListener for modern browsers.

onerror

  • Seems to work for IE if script debugging is turned off. See this confusing post for more insight. It's not easy to parse.
  • We may not support IE in a developer mode for sending logs since it takes over the onerror event handler.
  • All the Logger.* functions work just fine.

:frowning: IE does not properly propagate the onerror window event. Specifically if the user is running IE there are some versions and scenarios that cause onerror not to fire.

Console Logging

As stated above when the console handler is used it makes a console.error call. In IE 8 console is not defined until the developer tools window is opened. Because of this you will not see any logs until you open the developer tools when using IE 8. There is a check to suppress the call attempt if console is not defined; you do not need to worry about erroneous errors.

Helpful links:

Good info on client logging:

  • opera, https://dev.opera.com/articles/client-side-error-logging/
  • opera, onerror, https://dev.opera.com/articles/better-error-handling-with-window-onerror/

Blink Logging signature:

  • https://mikewest.org/2013/08/debugging-runtime-errors-with-window-onerror

window.onerror:

  • mdn, https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers.onerror
  • chrome console, http://stackoverflow.com/questions/16192464/window-onerror-not-working-in-chrome

Some existing options on the market that are either too bulky or require too much work on the end user.

Issues

Please browse our existing issues before logging new issues.

Contributing

See CONTRIBUTING.md

License

Copyright 2015 Cerner Innovation, Inc.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.