Repository files navigation

FileMaker-Logger

A modular open-source logging framework for Claris FileMaker.

Components

  • Logger module: Provide an interface for logging.
    • Call this module from any script you want to create a log entry from.
  • Log Writer modules: Save log data to a single destination.
    • Call Log Writers from the Logger module.
  • Log Viewer modules: View log data.
    • Provide a user interface for viewing log data.

File List

  • Log.fmp12: File that you can host on your server to save log data to.
    • It has been designed as both a self-standing logging application as well as an example file/documentation for the included Log-related modules.
  • ExampleApp.fmp12: This holds the code that should be copied into your FileMaker file.
  • LogWriters directory: Additional Log Writer modules.

Getting Started

Most documentation for this project exists in READ ME scripts:

  • File Module > READ ME
  • Modules > Logger > Logger: READ ME
  • Modules > Log Writer: FM > Log Writer: FM: READ ME
  • Modules > Log Viewer: FM > Log Viewer: FM: READ ME

Consider using additional LogWriters. View the READ ME scripts in each of those files if you choose to implement one.

Log Level

By including a log level with each call to the Logger module, it allows you to write your scripts with debugging code right from the start and leave that debugging code in your script while in production. By using the LogWriteEnabled function, you can reduce the overhead imposed by this logging method on code in production by only calling the Logger module if logs of the specified level are supposed to be saved.

An example of this implementation can be seen in the PluginChecker.fmp12 file from my PluginManager project. Open the ~PluginChecker: Test Plugin ( ... ) script from the Modules > PluginChecker > PluginChecker: Private folder. That script uses the $$PLUGINCHECKER.LOGLEVELTOWRITE global variable instead of the LogWriteEnabled custom function, but the concept is the same. It also calls the local PluginChecker: Config: Create Log Entry script instead of directly calling the Logger module, which allows users to configure logging (or not), however they choose.

In the ~PluginChecker: Test Plugin ( ... ) script, you will see many calls to the ...Create Log Entry script, but most of them are only called if the log level to write is defined as 4 (debug) or 5 (trace). This means that $$PLUGINCHECKER.LOGLEVELTOWRITE can be set to 1-3 while in production and the module would only create a single log entry and only if it encountered an error. Or, while developing/debugging an issue, you can set $$PLUGINCHECKER.LOGLEVELTOWRITE to 4 or 5 and get many log entries which explain every major decision the script made, along with the data that existed at the time that decision was made.

When using this method of debugging, you don't have to remove your debugging code before going to production mode. That also means you don't have to add that code again when you run into issues while in production. It's also platform agnostic, this method of debugging works just as well for a script being run on the server as it does for one run in FileMaker Pro, or Pro Advanced.

Recommended log levels and when to use them

1 Error

The system is in distress, customers are probably being affected (or will soon be) and the fix probably requires human intervention. The "2AM rule" applies here- if you're on call, do you want to be woken up at 2AM if this condition happens? If yes, then log it as "error".

2 Warn

An unexpected technical or business event happened, customers may be affected, but probably no immediate human intervention is required. On call people won't be called immediately, but support personnel will want to review these issues asap to understand what the impact is. Basically any issue that needs to be tracked but may not require immediate intervention.

3 Info

Things we want to see at high volume in case we need to forensically analyze an issue. System lifecycle events (system start, stop) go here. "Session" lifecycle events (login, logout, etc.) go here. Significant boundary events should be considered as well (e.g. database calls, remote API calls). Typical business exceptions can go here (e.g. login failed due to bad credentials). Any other event you think you'll need to see in production at high volume goes here.

4 Debug

Just about everything that doesn't make the "info" cut. Any message that is helpful in tracking the flow through the system and isolating issues, especially during the development and QA phases. We use "debug" level logs for entry/exit of most non-trivial methods and marking interesting events and decision points inside methods.

5 Trace

For extremely detailed and potentially high volume logs that you don't typically want enabled even during normal development. Examples include dumping a full object hierarchy, logging some state during every iteration of a large loop, etc.

About

A modular open-source logging framework for FileMaker.

Resources

Stars

20 stars

Watchers

8 watching

Forks

Releases

Packages

Contributors

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

FileMaker-Logger

A modular open-source logging framework for Claris FileMaker.

Components

  • Logger module: Provide an interface for logging.
    • Call this module from any script you want to create a log entry from.
  • Log Writer modules: Save log data to a single destination.
    • Call Log Writers from the Logger module.
  • Log Viewer modules: View log data.
    • Provide a user interface for viewing log data.

File List

  • Log.fmp12: File that you can host on your server to save log data to.
    • It has been designed as both a self-standing logging application as well as an example file/documentation for the included Log-related modules.
  • ExampleApp.fmp12: This holds the code that should be copied into your FileMaker file.
  • LogWriters directory: Additional Log Writer modules.

Getting Started

Most documentation for this project exists in READ ME scripts:

  • File Module > READ ME
  • Modules > Logger > Logger: READ ME
  • Modules > Log Writer: FM > Log Writer: FM: READ ME
  • Modules > Log Viewer: FM > Log Viewer: FM: READ ME

Consider using additional LogWriters. View the READ ME scripts in each of those files if you choose to implement one.

Log Level

By including a log level with each call to the Logger module, it allows you to write your scripts with debugging code right from the start and leave that debugging code in your script while in production. By using the LogWriteEnabled function, you can reduce the overhead imposed by this logging method on code in production by only calling the Logger module if logs of the specified level are supposed to be saved.

An example of this implementation can be seen in the PluginChecker.fmp12 file from my PluginManager project. Open the ~PluginChecker: Test Plugin ( ... ) script from the Modules > PluginChecker > PluginChecker: Private folder. That script uses the $$PLUGINCHECKER.LOGLEVELTOWRITE global variable instead of the LogWriteEnabled custom function, but the concept is the same. It also calls the local PluginChecker: Config: Create Log Entry script instead of directly calling the Logger module, which allows users to configure logging (or not), however they choose.

In the ~PluginChecker: Test Plugin ( ... ) script, you will see many calls to the ...Create Log Entry script, but most of them are only called if the log level to write is defined as 4 (debug) or 5 (trace). This means that $$PLUGINCHECKER.LOGLEVELTOWRITE can be set to 1-3 while in production and the module would only create a single log entry and only if it encountered an error. Or, while developing/debugging an issue, you can set $$PLUGINCHECKER.LOGLEVELTOWRITE to 4 or 5 and get many log entries which explain every major decision the script made, along with the data that existed at the time that decision was made.

When using this method of debugging, you don't have to remove your debugging code before going to production mode. That also means you don't have to add that code again when you run into issues while in production. It's also platform agnostic, this method of debugging works just as well for a script being run on the server as it does for one run in FileMaker Pro, or Pro Advanced.

Recommended log levels and when to use them

1 Error

The system is in distress, customers are probably being affected (or will soon be) and the fix probably requires human intervention. The "2AM rule" applies here- if you're on call, do you want to be woken up at 2AM if this condition happens? If yes, then log it as "error".

2 Warn

An unexpected technical or business event happened, customers may be affected, but probably no immediate human intervention is required. On call people won't be called immediately, but support personnel will want to review these issues asap to understand what the impact is. Basically any issue that needs to be tracked but may not require immediate intervention.

3 Info

Things we want to see at high volume in case we need to forensically analyze an issue. System lifecycle events (system start, stop) go here. "Session" lifecycle events (login, logout, etc.) go here. Significant boundary events should be considered as well (e.g. database calls, remote API calls). Typical business exceptions can go here (e.g. login failed due to bad credentials). Any other event you think you'll need to see in production at high volume goes here.

4 Debug

Just about everything that doesn't make the "info" cut. Any message that is helpful in tracking the flow through the system and isolating issues, especially during the development and QA phases. We use "debug" level logs for entry/exit of most non-trivial methods and marking interesting events and decision points inside methods.

5 Trace

For extremely detailed and potentially high volume logs that you don't typically want enabled even during normal development. Examples include dumping a full object hierarchy, logging some state during every iteration of a large loop, etc.

About

A modular open-source logging framework for FileMaker.

Resources

Stars

20 stars

Watchers

8 watching

Forks

Releases

Packages

Contributors

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

FileMaker-Logger

A modular open-source logging framework for Claris FileMaker.

Components

  • Logger module: Provide an interface for logging.
    • Call this module from any script you want to create a log entry from.
  • Log Writer modules: Save log data to a single destination.
    • Call Log Writers from the Logger module.
  • Log Viewer modules: View log data.
    • Provide a user interface for viewing log data.

File List

  • Log.fmp12: File that you can host on your server to save log data to.
    • It has been designed as both a self-standing logging application as well as an example file/documentation for the included Log-related modules.
  • ExampleApp.fmp12: This holds the code that should be copied into your FileMaker file.
  • LogWriters directory: Additional Log Writer modules.

Getting Started

Most documentation for this project exists in READ ME scripts:

  • File Module > READ ME
  • Modules > Logger > Logger: READ ME
  • Modules > Log Writer: FM > Log Writer: FM: READ ME
  • Modules > Log Viewer: FM > Log Viewer: FM: READ ME

Consider using additional LogWriters. View the READ ME scripts in each of those files if you choose to implement one.

Log Level

By including a log level with each call to the Logger module, it allows you to write your scripts with debugging code right from the start and leave that debugging code in your script while in production. By using the LogWriteEnabled function, you can reduce the overhead imposed by this logging method on code in production by only calling the Logger module if logs of the specified level are supposed to be saved.

An example of this implementation can be seen in the PluginChecker.fmp12 file from my PluginManager project. Open the ~PluginChecker: Test Plugin ( ... ) script from the Modules > PluginChecker > PluginChecker: Private folder. That script uses the $$PLUGINCHECKER.LOGLEVELTOWRITE global variable instead of the LogWriteEnabled custom function, but the concept is the same. It also calls the local PluginChecker: Config: Create Log Entry script instead of directly calling the Logger module, which allows users to configure logging (or not), however they choose.

In the ~PluginChecker: Test Plugin ( ... ) script, you will see many calls to the ...Create Log Entry script, but most of them are only called if the log level to write is defined as 4 (debug) or 5 (trace). This means that $$PLUGINCHECKER.LOGLEVELTOWRITE can be set to 1-3 while in production and the module would only create a single log entry and only if it encountered an error. Or, while developing/debugging an issue, you can set $$PLUGINCHECKER.LOGLEVELTOWRITE to 4 or 5 and get many log entries which explain every major decision the script made, along with the data that existed at the time that decision was made.

When using this method of debugging, you don't have to remove your debugging code before going to production mode. That also means you don't have to add that code again when you run into issues while in production. It's also platform agnostic, this method of debugging works just as well for a script being run on the server as it does for one run in FileMaker Pro, or Pro Advanced.

Recommended log levels and when to use them

1 Error

The system is in distress, customers are probably being affected (or will soon be) and the fix probably requires human intervention. The "2AM rule" applies here- if you're on call, do you want to be woken up at 2AM if this condition happens? If yes, then log it as "error".

2 Warn

An unexpected technical or business event happened, customers may be affected, but probably no immediate human intervention is required. On call people won't be called immediately, but support personnel will want to review these issues asap to understand what the impact is. Basically any issue that needs to be tracked but may not require immediate intervention.

3 Info

Things we want to see at high volume in case we need to forensically analyze an issue. System lifecycle events (system start, stop) go here. "Session" lifecycle events (login, logout, etc.) go here. Significant boundary events should be considered as well (e.g. database calls, remote API calls). Typical business exceptions can go here (e.g. login failed due to bad credentials). Any other event you think you'll need to see in production at high volume goes here.

4 Debug

Just about everything that doesn't make the "info" cut. Any message that is helpful in tracking the flow through the system and isolating issues, especially during the development and QA phases. We use "debug" level logs for entry/exit of most non-trivial methods and marking interesting events and decision points inside methods.

5 Trace

For extremely detailed and potentially high volume logs that you don't typically want enabled even during normal development. Examples include dumping a full object hierarchy, logging some state during every iteration of a large loop, etc.

About

A modular open-source logging framework for FileMaker.

Resources

Stars

20 stars

Watchers

8 watching

Forks

Releases

Packages

Contributors

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

FileMaker-Logger

A modular open-source logging framework for Claris FileMaker.

Components

  • Logger module: Provide an interface for logging.
    • Call this module from any script you want to create a log entry from.
  • Log Writer modules: Save log data to a single destination.
    • Call Log Writers from the Logger module.
  • Log Viewer modules: View log data.
    • Provide a user interface for viewing log data.

File List

  • Log.fmp12: File that you can host on your server to save log data to.
    • It has been designed as both a self-standing logging application as well as an example file/documentation for the included Log-related modules.
  • ExampleApp.fmp12: This holds the code that should be copied into your FileMaker file.
  • LogWriters directory: Additional Log Writer modules.

Getting Started

Most documentation for this project exists in READ ME scripts:

  • File Module > READ ME
  • Modules > Logger > Logger: READ ME
  • Modules > Log Writer: FM > Log Writer: FM: READ ME
  • Modules > Log Viewer: FM > Log Viewer: FM: READ ME

Consider using additional LogWriters. View the READ ME scripts in each of those files if you choose to implement one.

Log Level

By including a log level with each call to the Logger module, it allows you to write your scripts with debugging code right from the start and leave that debugging code in your script while in production. By using the LogWriteEnabled function, you can reduce the overhead imposed by this logging method on code in production by only calling the Logger module if logs of the specified level are supposed to be saved.

An example of this implementation can be seen in the PluginChecker.fmp12 file from my PluginManager project. Open the ~PluginChecker: Test Plugin ( ... ) script from the Modules > PluginChecker > PluginChecker: Private folder. That script uses the $$PLUGINCHECKER.LOGLEVELTOWRITE global variable instead of the LogWriteEnabled custom function, but the concept is the same. It also calls the local PluginChecker: Config: Create Log Entry script instead of directly calling the Logger module, which allows users to configure logging (or not), however they choose.

In the ~PluginChecker: Test Plugin ( ... ) script, you will see many calls to the ...Create Log Entry script, but most of them are only called if the log level to write is defined as 4 (debug) or 5 (trace). This means that $$PLUGINCHECKER.LOGLEVELTOWRITE can be set to 1-3 while in production and the module would only create a single log entry and only if it encountered an error. Or, while developing/debugging an issue, you can set $$PLUGINCHECKER.LOGLEVELTOWRITE to 4 or 5 and get many log entries which explain every major decision the script made, along with the data that existed at the time that decision was made.

When using this method of debugging, you don't have to remove your debugging code before going to production mode. That also means you don't have to add that code again when you run into issues while in production. It's also platform agnostic, this method of debugging works just as well for a script being run on the server as it does for one run in FileMaker Pro, or Pro Advanced.

Recommended log levels and when to use them

1 Error

The system is in distress, customers are probably being affected (or will soon be) and the fix probably requires human intervention. The "2AM rule" applies here- if you're on call, do you want to be woken up at 2AM if this condition happens? If yes, then log it as "error".

2 Warn

An unexpected technical or business event happened, customers may be affected, but probably no immediate human intervention is required. On call people won't be called immediately, but support personnel will want to review these issues asap to understand what the impact is. Basically any issue that needs to be tracked but may not require immediate intervention.

3 Info

Things we want to see at high volume in case we need to forensically analyze an issue. System lifecycle events (system start, stop) go here. "Session" lifecycle events (login, logout, etc.) go here. Significant boundary events should be considered as well (e.g. database calls, remote API calls). Typical business exceptions can go here (e.g. login failed due to bad credentials). Any other event you think you'll need to see in production at high volume goes here.

4 Debug

Just about everything that doesn't make the "info" cut. Any message that is helpful in tracking the flow through the system and isolating issues, especially during the development and QA phases. We use "debug" level logs for entry/exit of most non-trivial methods and marking interesting events and decision points inside methods.

5 Trace

For extremely detailed and potentially high volume logs that you don't typically want enabled even during normal development. Examples include dumping a full object hierarchy, logging some state during every iteration of a large loop, etc.

About

A modular open-source logging framework for FileMaker.

Resources

Stars

20 stars

Watchers

8 watching

Forks

Releases

Packages

Contributors

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

FileMaker-Logger

A modular open-source logging framework for Claris FileMaker.

Components

  • Logger module: Provide an interface for logging.
    • Call this module from any script you want to create a log entry from.
  • Log Writer modules: Save log data to a single destination.
    • Call Log Writers from the Logger module.
  • Log Viewer modules: View log data.
    • Provide a user interface for viewing log data.

File List

  • Log.fmp12: File that you can host on your server to save log data to.
    • It has been designed as both a self-standing logging application as well as an example file/documentation for the included Log-related modules.
  • ExampleApp.fmp12: This holds the code that should be copied into your FileMaker file.
  • LogWriters directory: Additional Log Writer modules.

Getting Started

Most documentation for this project exists in READ ME scripts:

  • File Module > READ ME
  • Modules > Logger > Logger: READ ME
  • Modules > Log Writer: FM > Log Writer: FM: READ ME
  • Modules > Log Viewer: FM > Log Viewer: FM: READ ME

Consider using additional LogWriters. View the READ ME scripts in each of those files if you choose to implement one.

Log Level

By including a log level with each call to the Logger module, it allows you to write your scripts with debugging code right from the start and leave that debugging code in your script while in production. By using the LogWriteEnabled function, you can reduce the overhead imposed by this logging method on code in production by only calling the Logger module if logs of the specified level are supposed to be saved.

An example of this implementation can be seen in the PluginChecker.fmp12 file from my PluginManager project. Open the ~PluginChecker: Test Plugin ( ... ) script from the Modules > PluginChecker > PluginChecker: Private folder. That script uses the $$PLUGINCHECKER.LOGLEVELTOWRITE global variable instead of the LogWriteEnabled custom function, but the concept is the same. It also calls the local PluginChecker: Config: Create Log Entry script instead of directly calling the Logger module, which allows users to configure logging (or not), however they choose.

In the ~PluginChecker: Test Plugin ( ... ) script, you will see many calls to the ...Create Log Entry script, but most of them are only called if the log level to write is defined as 4 (debug) or 5 (trace). This means that $$PLUGINCHECKER.LOGLEVELTOWRITE can be set to 1-3 while in production and the module would only create a single log entry and only if it encountered an error. Or, while developing/debugging an issue, you can set $$PLUGINCHECKER.LOGLEVELTOWRITE to 4 or 5 and get many log entries which explain every major decision the script made, along with the data that existed at the time that decision was made.

When using this method of debugging, you don't have to remove your debugging code before going to production mode. That also means you don't have to add that code again when you run into issues while in production. It's also platform agnostic, this method of debugging works just as well for a script being run on the server as it does for one run in FileMaker Pro, or Pro Advanced.

Recommended log levels and when to use them

1 Error

The system is in distress, customers are probably being affected (or will soon be) and the fix probably requires human intervention. The "2AM rule" applies here- if you're on call, do you want to be woken up at 2AM if this condition happens? If yes, then log it as "error".

2 Warn

An unexpected technical or business event happened, customers may be affected, but probably no immediate human intervention is required. On call people won't be called immediately, but support personnel will want to review these issues asap to understand what the impact is. Basically any issue that needs to be tracked but may not require immediate intervention.

3 Info

Things we want to see at high volume in case we need to forensically analyze an issue. System lifecycle events (system start, stop) go here. "Session" lifecycle events (login, logout, etc.) go here. Significant boundary events should be considered as well (e.g. database calls, remote API calls). Typical business exceptions can go here (e.g. login failed due to bad credentials). Any other event you think you'll need to see in production at high volume goes here.

4 Debug

Just about everything that doesn't make the "info" cut. Any message that is helpful in tracking the flow through the system and isolating issues, especially during the development and QA phases. We use "debug" level logs for entry/exit of most non-trivial methods and marking interesting events and decision points inside methods.

5 Trace

For extremely detailed and potentially high volume logs that you don't typically want enabled even during normal development. Examples include dumping a full object hierarchy, logging some state during every iteration of a large loop, etc.

About

A modular open-source logging framework for FileMaker.

Resources

Stars

20 stars

Watchers

8 watching

Forks

Releases

Packages

Contributors

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

FileMaker-Logger

A modular open-source logging framework for Claris FileMaker.

Components

  • Logger module: Provide an interface for logging.
    • Call this module from any script you want to create a log entry from.
  • Log Writer modules: Save log data to a single destination.
    • Call Log Writers from the Logger module.
  • Log Viewer modules: View log data.
    • Provide a user interface for viewing log data.

File List

  • Log.fmp12: File that you can host on your server to save log data to.
    • It has been designed as both a self-standing logging application as well as an example file/documentation for the included Log-related modules.
  • ExampleApp.fmp12: This holds the code that should be copied into your FileMaker file.
  • LogWriters directory: Additional Log Writer modules.

Getting Started

Most documentation for this project exists in READ ME scripts:

  • File Module > READ ME
  • Modules > Logger > Logger: READ ME
  • Modules > Log Writer: FM > Log Writer: FM: READ ME
  • Modules > Log Viewer: FM > Log Viewer: FM: READ ME

Consider using additional LogWriters. View the READ ME scripts in each of those files if you choose to implement one.

Log Level

By including a log level with each call to the Logger module, it allows you to write your scripts with debugging code right from the start and leave that debugging code in your script while in production. By using the LogWriteEnabled function, you can reduce the overhead imposed by this logging method on code in production by only calling the Logger module if logs of the specified level are supposed to be saved.

An example of this implementation can be seen in the PluginChecker.fmp12 file from my PluginManager project. Open the ~PluginChecker: Test Plugin ( ... ) script from the Modules > PluginChecker > PluginChecker: Private folder. That script uses the $$PLUGINCHECKER.LOGLEVELTOWRITE global variable instead of the LogWriteEnabled custom function, but the concept is the same. It also calls the local PluginChecker: Config: Create Log Entry script instead of directly calling the Logger module, which allows users to configure logging (or not), however they choose.

In the ~PluginChecker: Test Plugin ( ... ) script, you will see many calls to the ...Create Log Entry script, but most of them are only called if the log level to write is defined as 4 (debug) or 5 (trace). This means that $$PLUGINCHECKER.LOGLEVELTOWRITE can be set to 1-3 while in production and the module would only create a single log entry and only if it encountered an error. Or, while developing/debugging an issue, you can set $$PLUGINCHECKER.LOGLEVELTOWRITE to 4 or 5 and get many log entries which explain every major decision the script made, along with the data that existed at the time that decision was made.

When using this method of debugging, you don't have to remove your debugging code before going to production mode. That also means you don't have to add that code again when you run into issues while in production. It's also platform agnostic, this method of debugging works just as well for a script being run on the server as it does for one run in FileMaker Pro, or Pro Advanced.

Recommended log levels and when to use them

1 Error

The system is in distress, customers are probably being affected (or will soon be) and the fix probably requires human intervention. The "2AM rule" applies here- if you're on call, do you want to be woken up at 2AM if this condition happens? If yes, then log it as "error".

2 Warn

An unexpected technical or business event happened, customers may be affected, but probably no immediate human intervention is required. On call people won't be called immediately, but support personnel will want to review these issues asap to understand what the impact is. Basically any issue that needs to be tracked but may not require immediate intervention.

3 Info

Things we want to see at high volume in case we need to forensically analyze an issue. System lifecycle events (system start, stop) go here. "Session" lifecycle events (login, logout, etc.) go here. Significant boundary events should be considered as well (e.g. database calls, remote API calls). Typical business exceptions can go here (e.g. login failed due to bad credentials). Any other event you think you'll need to see in production at high volume goes here.

4 Debug

Just about everything that doesn't make the "info" cut. Any message that is helpful in tracking the flow through the system and isolating issues, especially during the development and QA phases. We use "debug" level logs for entry/exit of most non-trivial methods and marking interesting events and decision points inside methods.

5 Trace

For extremely detailed and potentially high volume logs that you don't typically want enabled even during normal development. Examples include dumping a full object hierarchy, logging some state during every iteration of a large loop, etc.

About

A modular open-source logging framework for FileMaker.

Resources

Stars

20 stars

Watchers

8 watching

Forks

Releases

Packages

Contributors

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

FileMaker-Logger

A modular open-source logging framework for Claris FileMaker.

Components

  • Logger module: Provide an interface for logging.
    • Call this module from any script you want to create a log entry from.
  • Log Writer modules: Save log data to a single destination.
    • Call Log Writers from the Logger module.
  • Log Viewer modules: View log data.
    • Provide a user interface for viewing log data.

File List

  • Log.fmp12: File that you can host on your server to save log data to.
    • It has been designed as both a self-standing logging application as well as an example file/documentation for the included Log-related modules.
  • ExampleApp.fmp12: This holds the code that should be copied into your FileMaker file.
  • LogWriters directory: Additional Log Writer modules.

Getting Started

Most documentation for this project exists in READ ME scripts:

  • File Module > READ ME
  • Modules > Logger > Logger: READ ME
  • Modules > Log Writer: FM > Log Writer: FM: READ ME
  • Modules > Log Viewer: FM > Log Viewer: FM: READ ME

Consider using additional LogWriters. View the READ ME scripts in each of those files if you choose to implement one.

Log Level

By including a log level with each call to the Logger module, it allows you to write your scripts with debugging code right from the start and leave that debugging code in your script while in production. By using the LogWriteEnabled function, you can reduce the overhead imposed by this logging method on code in production by only calling the Logger module if logs of the specified level are supposed to be saved.

An example of this implementation can be seen in the PluginChecker.fmp12 file from my PluginManager project. Open the ~PluginChecker: Test Plugin ( ... ) script from the Modules > PluginChecker > PluginChecker: Private folder. That script uses the $$PLUGINCHECKER.LOGLEVELTOWRITE global variable instead of the LogWriteEnabled custom function, but the concept is the same. It also calls the local PluginChecker: Config: Create Log Entry script instead of directly calling the Logger module, which allows users to configure logging (or not), however they choose.

In the ~PluginChecker: Test Plugin ( ... ) script, you will see many calls to the ...Create Log Entry script, but most of them are only called if the log level to write is defined as 4 (debug) or 5 (trace). This means that $$PLUGINCHECKER.LOGLEVELTOWRITE can be set to 1-3 while in production and the module would only create a single log entry and only if it encountered an error. Or, while developing/debugging an issue, you can set $$PLUGINCHECKER.LOGLEVELTOWRITE to 4 or 5 and get many log entries which explain every major decision the script made, along with the data that existed at the time that decision was made.

When using this method of debugging, you don't have to remove your debugging code before going to production mode. That also means you don't have to add that code again when you run into issues while in production. It's also platform agnostic, this method of debugging works just as well for a script being run on the server as it does for one run in FileMaker Pro, or Pro Advanced.

Recommended log levels and when to use them

1 Error

The system is in distress, customers are probably being affected (or will soon be) and the fix probably requires human intervention. The "2AM rule" applies here- if you're on call, do you want to be woken up at 2AM if this condition happens? If yes, then log it as "error".

2 Warn

An unexpected technical or business event happened, customers may be affected, but probably no immediate human intervention is required. On call people won't be called immediately, but support personnel will want to review these issues asap to understand what the impact is. Basically any issue that needs to be tracked but may not require immediate intervention.

3 Info

Things we want to see at high volume in case we need to forensically analyze an issue. System lifecycle events (system start, stop) go here. "Session" lifecycle events (login, logout, etc.) go here. Significant boundary events should be considered as well (e.g. database calls, remote API calls). Typical business exceptions can go here (e.g. login failed due to bad credentials). Any other event you think you'll need to see in production at high volume goes here.

4 Debug

Just about everything that doesn't make the "info" cut. Any message that is helpful in tracking the flow through the system and isolating issues, especially during the development and QA phases. We use "debug" level logs for entry/exit of most non-trivial methods and marking interesting events and decision points inside methods.

5 Trace

For extremely detailed and potentially high volume logs that you don't typically want enabled even during normal development. Examples include dumping a full object hierarchy, logging some state during every iteration of a large loop, etc.

About

A modular open-source logging framework for FileMaker.

Resources

Stars

20 stars

Watchers

8 watching

Forks

Releases

Packages

Contributors

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

FileMaker-Logger

A modular open-source logging framework for Claris FileMaker.

Components

  • Logger module: Provide an interface for logging.
    • Call this module from any script you want to create a log entry from.
  • Log Writer modules: Save log data to a single destination.
    • Call Log Writers from the Logger module.
  • Log Viewer modules: View log data.
    • Provide a user interface for viewing log data.

File List

  • Log.fmp12: File that you can host on your server to save log data to.
    • It has been designed as both a self-standing logging application as well as an example file/documentation for the included Log-related modules.
  • ExampleApp.fmp12: This holds the code that should be copied into your FileMaker file.
  • LogWriters directory: Additional Log Writer modules.

Getting Started

Most documentation for this project exists in READ ME scripts:

  • File Module > READ ME
  • Modules > Logger > Logger: READ ME
  • Modules > Log Writer: FM > Log Writer: FM: READ ME
  • Modules > Log Viewer: FM > Log Viewer: FM: READ ME

Consider using additional LogWriters. View the READ ME scripts in each of those files if you choose to implement one.

Log Level

By including a log level with each call to the Logger module, it allows you to write your scripts with debugging code right from the start and leave that debugging code in your script while in production. By using the LogWriteEnabled function, you can reduce the overhead imposed by this logging method on code in production by only calling the Logger module if logs of the specified level are supposed to be saved.

An example of this implementation can be seen in the PluginChecker.fmp12 file from my PluginManager project. Open the ~PluginChecker: Test Plugin ( ... ) script from the Modules > PluginChecker > PluginChecker: Private folder. That script uses the $$PLUGINCHECKER.LOGLEVELTOWRITE global variable instead of the LogWriteEnabled custom function, but the concept is the same. It also calls the local PluginChecker: Config: Create Log Entry script instead of directly calling the Logger module, which allows users to configure logging (or not), however they choose.

In the ~PluginChecker: Test Plugin ( ... ) script, you will see many calls to the ...Create Log Entry script, but most of them are only called if the log level to write is defined as 4 (debug) or 5 (trace). This means that $$PLUGINCHECKER.LOGLEVELTOWRITE can be set to 1-3 while in production and the module would only create a single log entry and only if it encountered an error. Or, while developing/debugging an issue, you can set $$PLUGINCHECKER.LOGLEVELTOWRITE to 4 or 5 and get many log entries which explain every major decision the script made, along with the data that existed at the time that decision was made.

When using this method of debugging, you don't have to remove your debugging code before going to production mode. That also means you don't have to add that code again when you run into issues while in production. It's also platform agnostic, this method of debugging works just as well for a script being run on the server as it does for one run in FileMaker Pro, or Pro Advanced.

Recommended log levels and when to use them

1 Error

The system is in distress, customers are probably being affected (or will soon be) and the fix probably requires human intervention. The "2AM rule" applies here- if you're on call, do you want to be woken up at 2AM if this condition happens? If yes, then log it as "error".

2 Warn

An unexpected technical or business event happened, customers may be affected, but probably no immediate human intervention is required. On call people won't be called immediately, but support personnel will want to review these issues asap to understand what the impact is. Basically any issue that needs to be tracked but may not require immediate intervention.

3 Info

Things we want to see at high volume in case we need to forensically analyze an issue. System lifecycle events (system start, stop) go here. "Session" lifecycle events (login, logout, etc.) go here. Significant boundary events should be considered as well (e.g. database calls, remote API calls). Typical business exceptions can go here (e.g. login failed due to bad credentials). Any other event you think you'll need to see in production at high volume goes here.

4 Debug

Just about everything that doesn't make the "info" cut. Any message that is helpful in tracking the flow through the system and isolating issues, especially during the development and QA phases. We use "debug" level logs for entry/exit of most non-trivial methods and marking interesting events and decision points inside methods.

5 Trace

For extremely detailed and potentially high volume logs that you don't typically want enabled even during normal development. Examples include dumping a full object hierarchy, logging some state during every iteration of a large loop, etc.

About

A modular open-source logging framework for FileMaker.

Resources

Stars

20 stars

Watchers

8 watching

Forks

Releases

Packages

Contributors