How to integrate PnP JS Core and SharePoint Framework logging systems

Introduction

Recently, I was playing with PnP JS Core library, which basically is a wrapper of SharePoint Rest API that allows us to easily use it.

I discovered some cool Features in this library which I really like them! For example, we are able to easily cache queries, do batches, and the library has a good Logging system, which actually is the main topic of this post.

Integrate Logging

So, this post is intended to show how to integrate two different logging systems when developing a SharePoint Framework web part.

Let´s share few documentation links to be aware which logging systems I am talking about:

After creating our SPFx web part, and installing sp-pnp-js, then let´s import both logging systems classes:

// import pnp and pnp logging system
import pnp, { Logger, FunctionListener, LogEntry, LogLevel } from "sp-pnp-js";
// import SPFx Logging system
import { Log } from "@microsoft/sp-core-library";

If we are using React to build our SPFx webpart, then we could use the following code in our React Component´s constructor:

////////////////////////////////////////////////////////////////////////
// enable Logging system
////////////////////////////////////////////////////////////////////////
// we will integrate PnP JS Logging System with SPFx Logging system
// 1. Logger object => PnP JS Logger
// https://github.com/SharePoint/PnP-JS-Core/wiki/Working-With:-Logging
// 2. Log object => SPFx Logger
// https://github.com/SharePoint/sp-dev-docs/wiki/Working-with-the-Logging-API
////////////////////////////////////////////////////////////////////////
// [PnP JS Logging] activate Info level
Logger.activeLogLevel = LogLevel.Info;
// [PnP JS Logging] create a custom FunctionListener to integrate PnP JS and SPFx Logging systems
const listener = new FunctionListener((entry: LogEntry) => {
// get React component name
const componentName: string = (this as any)._reactInternalInstance._currentElement.props.description;
// mapping betwween PnP JS Log types and SPFx logging methods
// instead of using switch we use object easy syntax
const logLevelConversion = { Verbose: "verbose", Info: "info", Warning: "warn", Error: "error" };
// create Message. Two importante notes here:
// 1. Use JSON.stringify to output everything. It´s helpful when some internal exception comes thru.
// 2. Use JavaScript´s Error constructor allows us to output more than 100 characters using SPFx logging
let formatedMessage;
if (entry.level === LogLevel.Error) {
formatedMessage = new Error(`Message: ${entry.message} Data: ${JSON.stringify(entry.data)}`);
// formatedMessage = `Message: ${entry.message} Data: ${JSON.stringify(entry.data)}`;
} else {
formatedMessage = `Message: ${entry.message} Data: ${JSON.stringify(entry.data)}`;
}
// [SPFx Logging] Calculate method to invoke verbose, info, warn or error
const method = logLevelConversion[LogLevel[entry.level]];
// [SPFx Logging] Call SPFx Logging system with the message received from PnP JS Logging
Log[method](componentName, formatedMessage);
});
// [PnP JS Logging] Once create the custom listerner we should subscribe to it
Logger.subscribe(listener);

We can see the comments as self-explanation how the integration have been done. So, basically we enable PnP JS Core Logging at Info level and we create a special FunctionListener to pass every message through SPFx Log system using the right method (verbose, info, warn or error).

Example

Let´s see an example how it works, imagine we have this code in which we are querying a library selecting a non-existing column called “assdafa”.

image

PnP JS will provide an internal error giving more detail, we can see it on the following image:

error log

Conclusion

Note that the source of the error is sp-loader instead of pnp-js, that is because we are using the FunctionListener to pass all the errors thru SPFx logger.

I created a SPFx webpart sample to demonstrate this PnP JS functionality. Please check it out and any feedback is welcome!

 

Author: José Quinto
Link: https://blog.josequinto.com/2017/04/30/how-to-integrate-pnp-js-core-and-sharepoint-framework-logging-systems/
Copyright Notice: All articles in this blog are licensed under CC BY-SA 4.0 unless stating additionally.