
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:
- SPFx Log class
- SPFx. Working with the Logging API
- PnP JS Logging implementation
- PnP JS. Working With: Logging
- React component logging with TypeScript
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”.
PnP JS will provide an internal error giving more detail, we can see it on the following image:
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!