Showing posts with label Pantheios. Show all posts
Showing posts with label Pantheios. Show all posts

Saturday, June 13, 2020

Pantheios.Ruby Tutorial, part 2: First Program

This is the second part in a series of tutorial posts illustrating how to use Pantheios.Ruby. The first part is here.

Project Setup

In this part we're going to do some basic project setup. Expert Rubyists may wish to skip to the next section.

First step is to create a git project. Create a new directory and do a Git init:

$ git init

I'm going to use Bundler, so next do a Bundle init:

$ bundle init

I happen to know that we'll be using recls.Ruby as well as Pantheios.Ruby, so let's edit the generated bundle file to look something like the following:

  # frozen_string_literal: true
  
  source "https://rubygems.org"
  
  git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
  
  gem "pantheios-ruby"  
  gem "recls-ruby"  

Then just bundle it:

$ bundle

All being well, add Gemfile and the newly generated Gemfile.lock into git and commit.

First Program

Ok, now on to the first program. First create the script searcher.rb and require and include both libraries, as follows:

  1 #! /usr/bin/env ruby
  2 
  3 require "pantheios"
  4 require "recls"
  5 
  6 include ::Pantheios
  7 

Give it a run to verify Bundler did its job ok.

$ ruby searcher.rb

Go ahead and commit that, then we'll make it a little interesting by doing a search and logging some output.

  1 #! /usr/bin/env ruby
  2 
  3 require "pantheios"
  4 require "recls"
  5 
  6 include ::Pantheios
  7 
  8 Recls.file_rsearch(nil, nil).each do |fe|
  9 
 10     log(:informational, "found '#{fe.search_relative_path}'")
 11 end 
 12    

This uses the Recls module function file_rsearch() to conduct a recursive search for files, returning an Enumerable object on which we call each passing the block that uses Pantheios.Ruby's log() method to record each item found. On my machine it produces the following output

[searcher, 70123163703220, 2020-06-14 09:31:35.142106, Informational]: found 'searcher.rb'
[searcher, 70123163703220, 2020-06-14 09:31:35.142559, Informational]: found 'Gemfile'
[searcher, 70123163703220, 2020-06-14 09:31:35.143248, Informational]: found 'Gemfile.lock'

In the next instalment we'll examine the aspects of this program and its output and make some customisations to what gets logged and in what form.


Friday, June 12, 2020

Pantheios.Ruby Tutorial, part 1: Basic Script

So, this'll be the first of a set of tutorials explaining how to use Pantheios.Ruby.

Install and Verify


The first thing to do is install it, which is done as simply as:

$ gem install pantheios-ruby

(You may need/prefer to download the latest gem from rubygems and install from a local gem file. You may need the right privileges, so could require sudo.)

You can then verify the installation with the one-line:

$ ruby -e 'require "pantheios" ; puts Pantheios::VERSION;'

and should see output such as:

0.22.0

Basic Script

Next, we'll create a minimally-featured script that does some logging. Using vim - I mean, what else is there?! - create a script hello_pantheios.rb with the following contents:

  #! /usr/bin/env ruby
  
  require "pantheios"
  
  include ::Pantheios
  
  log(:notice, "Hello, World of Logs!")

and then execute as follows:

$ ruby hello_pantheios.rb

you'll see output such as:

[hello_pantheios, 70345600268220, 2020-06-13 10:09:21.867107, Notice]: Hello, World of Logs!

Coming up:

In the next post we'll create a first version of a file-system search program with which we will illustrate a whole raft of Pantheios.Ruby features, including (but not limited to):

  • using different severity levels and ascribing meaning to those levels;
  • filtering based on severity levels, including using front-ends to make decisions about which severity levels will be output;
  • choosing back-ends, i.e. where logged output goes, including:
    • logging to the console;
    • logging to the console with severity level-related colours;
    • files;
    • syslog;
    • Ruby's standard logger;
    • log4r;
    • ... and so on;
  • naming threads;
  • customising the prefix - the bit above that contains "[hello_pantheios, 70345600268220, 2020-06-13 10:09:21.867107, Notice]: ";
  • ... and many more things I can't think of right now. That's why we're going to write an actually useful program to exercise it.


Friday, June 5, 2020

Custom Severity Levels with Pantheios C/C++ project

Been a bit of demand for this one, so here we go, in as few words as possible.

Stock Severity Levels

Out of the box, up to the present version (1.0.1 beta 218) the Pantheios C/C++ library comes with eight stock severity levels, as follows:


Manifest constantIntegral valueString form (1)
PANTHEIOS_SEV_EMERGENCY0"Emergency"
PANTHEIOS_SEV_ALERT1"Alert"
PANTHEIOS_SEV_CRITICAL2"Critical"
PANTHEIOS_SEV_ERROR3"Error"
PANTHEIOS_SEV_WARNING4"Warning"
PANTHEIOS_SEV_NOTICE5"Notice"
PANTHEIOS_SEV_INFORMATIONAL   6"Informational"   
PANTHEIOS_SEV_DEBUG7"Debug"

1. as obtained by pantheios_getStockSeverityString()

These are defined in the file pantheios/pantheios.h and are available for both C and C++ compilation units. Additionally, for C++ compilation units the following pseudo-constants are available:


C++ pseudo-constant (2)Integral ValueCorresponding constant
pantheios::emergency0PANTHEIOS_SEV_EMERGENCY
pantheios::alert1PANTHEIOS_SEV_ALERT
pantheios::critical2PANTHEIOS_SEV_CRITICAL
pantheios::error3PANTHEIOS_SEV_ERROR
pantheios::warning4PANTHEIOS_SEV_WARNING
pantheios::notice5PANTHEIOS_SEV_NOTICE
pantheios::informational   6PANTHEIOS_SEV_INFORMATIONAL
pantheios::debug7PANTHEIOS_SEV_DEBUG

2. these are defined 

These C++-only pseudo-constants also facilitate easily the use of extended severity information, but that's a topic for another time.

The string forms' C-style strings and string lengths are obtained, respectively, via the pantheios_getStockSeverityString() and pantheios_getStockSeverityStringLength() API functions.

Custom Severity Levels

If you want to use a different set of severities, then you must do the following:
  1. #define the preprocessor symbol PANTHEIOS_NO_STOCK_LEVELS;
  2. link to a back-end of your own that understands your custom severity levels.

Here's a C-program illustrating how to do this (with as much detail as possible elided for brevity):



#define PANTHEIOS_NO_STOCK_LEVELS /* suppress stock severity levels */

#include ⟨pantheios/pantheios.h⟩

/* some log4j-like levels */

enum CustomSeverityLevel_t
{
  CSL_Fatal = 0,
  CSL_Error = 3,
  CSL_Warn  = 4,
  CSL_Info  = 6,
  CSL_Debug = 7,
};

/* the application */

int main()
{
  int retCode = EXIT_SUCCESS;
  int res;

  res = pantheios_init();

  if(0 != res)
  {
    fprintf(stderr, "Failed to initialise the Pantheios libraries: %s\n", pantheios_getInitCodeString(res));

    retCode = EXIT_FAILURE;
  }
  else
  {
    pantheios_logputs(CSL_Info, PANTHEIOS_LITERAL_STRING("pantheios_logputs() can output a single C-style string"));


    . . . //rest of program logic, including more pantheios_logputs() / pantheios_logprintf() statements


    pantheios_uninit();
  }

  return retCode;
}

/* the custom back-end */

#include ⟨pantheios/backend.h⟩
#include ⟨pantheios/init_codes.h⟩
#include ⟨pantheios/strdup.h⟩

PANTHEIOS_CALL(int) pantheios_be_init(
  PAN_CHAR_T const* processIdentity
, void*             reserved
, void**            ptoken
)
{
  ((void)reserved);

  *ptoken = pantheios_util_strdup_nothrow(processIdentity);

  return (NULL == *ptoken) ? PANTHEIOS_INIT_RC_OUT_OF_MEMORY : PANTHEIOS_INIT_RC_SUCCESS;
}

PANTHEIOS_CALL(void) pantheios_be_uninit(void *token)
{
  pantheios_util_strfree((PAN_CHAR_T*)(token));
}

PANTHEIOS_CALL(int) pantheios_be_logEntry(  
  void*             feToken
, void*             beToken
, int               severity
, PAN_CHAR_T const* entry
, size_t            cchEntry
)
{
  PAN_CHAR_T const* sevString;
  PAN_CHAR_T const* processId = (PAN_CHAR_T const*)(beToken);

  ((void)feToken);

  switch (severity)
  {
  case CSL_Fatal:
    sevString = PANTHEIOS_LITERAL_STRING("Fatal");
    break;
  case CSL_Error:
    sevString = PANTHEIOS_LITERAL_STRING("Error");
    break;
  case CSL_Warn:
    sevString = PANTHEIOS_LITERAL_STRING("Warn");
    break;
  case CSL_Info:
    sevString = PANTHEIOS_LITERAL_STRING("Info");
    break;
  case CSL_Debug:
    sevString = PANTHEIOS_LITERAL_STRING("Debug");
    break;
  default:
    sevString = PANTHEIOS_LITERAL_STRING("");
    break;
  }

#ifdef PANTHEIOS_USE_WIDE_STRINGS
  return fwprintf(
        stderr
      , L"[%s; %s]: %.*s\n"
      , processId
      , sevString
      , (int)cchEntry, entry
      );
#else /* ? PANTHEIOS_USE_WIDE_STRINGS */
  return fprintf(
        stderr
      , "[%s; %s]: %.*s\n"
      , processId
      , sevString
      , (int)cchEntry, entry
      );
#endif /* PANTHEIOS_USE_WIDE_STRINGS */
}

Tuesday, February 5, 2019

Coming in 2019: Pantheios 1 (non-beta); Pantheios 2

Ok, so it's been a heck of a long while since Pantheios' first beta was released. The last released beta was 219 (!), on 28th January 2017. There's been a fair amount of useful work on the library since then, but not released.

(As has been obvious since the outset of its release into the world, having the first version number as 1.0.1 and then just bumping the beta was crazy optimistic, and in practice just crazy. This very aspect has hindered speed of progress, as it's worked against the principle of release early, release often.)

There's also been a lot of change in "the ideal conception of Pantheios in C/C++" in this time. There are no massive changes, but there are some important differences that will require a bump in major number, which will be outlined in posts in the near future.

Both of the above (as yet unreleased) works have arisen due to use and commercial customisations I've been doing for a client, in which Pantheios has seen tremendous use in exacting circumstances. (I say this to reassure that the project is not dead, not even resting, stunned, or pining for the fjords. It is alive, and it will be sprouting wings again into the world this year.)

So, without much further ado, the coming changes of the Pantheios project are:
  • The existing Pantheios project (1.0.1-bXXX) will be mothballed;
  • The current state of Pantheios will be effectively rendered in another project, Pantheios1;
  • The new, improved version will be rendered in another project, Pantheios2, sometime before the middle of the year. Subsequent posts will explain the new/changed features.


Sunday, September 27, 2015

Use of the showPlus format flag

Pantheios 1.0.1 beta 215 introduces the showPlus format flag, which causes leading pluses to be applied to integers (just as leading minuses will appear for negative numbers).

It is used as follows:

#include <pantheios/pan.hpp>
#include <pantheios/inserters/i.hpp>

int main()
{
  pan::log_INFORMATIONAL("log -10:");
  pan::log_INFORMATIONAL("without showPlus: '", pan::i(-10), "'");
  pan::log_INFORMATIONAL("with    showPlus: '", pan::i(-10, 0, pan::fmt::showPlus), "'");
  pan::log_INFORMATIONAL("----------\n");

  pan::log_INFORMATIONAL("log +10:");
  pan::log_INFORMATIONAL("without showPlus: '", pan::i(+10), "'");
  pan::log_INFORMATIONAL("with    showPlus: '", pan::i(+10, 0, pan::fmt::showPlus), "'");
  pan::log_INFORMATIONAL("----------\n");


  pan::log_INFORMATIONAL("log -10 into 10-width:");
  pan::log_INFORMATIONAL("without showPlus: '", pan::i(-10, 10, 0), "'");
  pan::log_INFORMATIONAL("with    showPlus: '", pan::i(-10, 10, pan::fmt::showPlus), "'");
  pan::log_INFORMATIONAL("----------\n");

  pan::log_INFORMATIONAL("log +10 into 10-width:");
  pan::log_INFORMATIONAL("without showPlus: '", pan::i(+10, 10, 0), "'");
  pan::log_INFORMATIONAL("with    showPlus: '", pan::i(+10, 10, pan::fmt::showPlus), "'");
  pan::log_INFORMATIONAL("----------\n");


  pan::log_INFORMATIONAL("log -10 into 10-width left-justified:");
  pan::log_INFORMATIONAL("without showPlus: '", pan::i(-10, -10, 0), "'");
  pan::log_INFORMATIONAL("with    showPlus: '", pan::i(-10, -10, pan::fmt::showPlus), "'");
  pan::log_INFORMATIONAL("----------\n");

  pan::log_INFORMATIONAL("log +10 into 10-width left-justified:");
  pan::log_INFORMATIONAL("without showPlus: '", pan::i(+10, -10, 0), "'");
  pan::log_INFORMATIONAL("with    showPlus: '", pan::i(+10, -10, pan::fmt::showPlus), "'");
  pan::log_INFORMATIONAL("----------\n");


  return 0;
}

PANTHEIOS_EXTERN_C PAN_CHAR_T const PANTHEIOS_FE_PROCESS_IDENTITY[] = PANTHEIOS_LITERAL_STRING("test.scratch.showPlus.integer");

which gives the output:

[test.scratch.showPlus.integer...]: log -10:
[test.scratch.showPlus.integer...]: without showPlus: '-10'
[test.scratch.showPlus.integer...]: with    showPlus: '-10'
[test.scratch.showPlus.integer...]: ----------

[test.scratch.showPlus.integer...]: log +10:
[test.scratch.showPlus.integer...]: without showPlus: '10'
[test.scratch.showPlus.integer...]: with    showPlus: '+10'
[test.scratch.showPlus.integer...]: ----------

[test.scratch.showPlus.integer...]: log -10 into 10-width:
[test.scratch.showPlus.integer...]: without showPlus: '       -10'
[test.scratch.showPlus.integer...]: with    showPlus: '       -10'
[test.scratch.showPlus.integer...]: ----------

[test.scratch.showPlus.integer...]: log +10 into 10-width:
[test.scratch.showPlus.integer...]: without showPlus: '        10'
[test.scratch.showPlus.integer...]: with    showPlus: '       +10'
[test.scratch.showPlus.integer...]: ----------

[test.scratch.showPlus.integer...]: log -10 into 10-width left-justified:
[test.scratch.showPlus.integer...]: without showPlus: '-10       '
[test.scratch.showPlus.integer...]: with    showPlus: '-10       '
[test.scratch.showPlus.integer...]: ----------

[test.scratch.showPlus.integer...]: log +10 into 10-width left-justified:
[test.scratch.showPlus.integer...]: without showPlus: '10        '
[test.scratch.showPlus.integer...]: with    showPlus: '+10       '
[test.scratch.showPlus.integer...]: ----------


GitHub access

Pantheios GitHub access now at:




Fork away!

Monday, January 10, 2011

Pantheios 1.0.1 beta 210 released: closing a vulnerability to badly written third-party libraries

The latest release of Pantheios - version 1.0.1 beta 210 - closes a vulnerability to implicit conversion of instances of fundamental types in the presence of badly-written third-party C++ libraries.

For reasons of robustness, Pantheios log statements do not accept instances of fundamental types - integers, floating-points, bool, char, and so on. Instead, users are advised to select from the set of stock inserter classes and functions provided with the library, or to define their own.

Consequently, and by design, statements such as the following will result in compilation errors:

  #include <pantheios/pantheios.hpp>

  pantheios::log_NOTICE("int: ", 10);

  pantheios::log_INFORMATIONAL("float: ", 1.23);

  pantheios::log_INFORMATIONAL("bool: ", true);

Instead, inserters should be used:

  #include <pantheios/pantheios.hpp>
  #include <pantheios/inserters/integer.hpp>
  #include <pantheios/inserters/real.hpp>
  #include <pantheios/inserters/boolean.hpp>

  pantheios::log_NOTICE("int: ", pantheios::integer(10));

  pantheios::log_INFORMATIONAL("float: ", pantheios::real(1.23));

  pantheios::log_INFORMATIONAL("bool: ", pantheios::boolean(true));

This can be expressed more succinctly by using namespace and inserter aliases:

  #include <pantheios/pan.hpp>
  #include <pantheios/inserters/i.hpp>
  #include <pantheios/inserters/real.hpp>
  #include <pantheios/inserters/b.hpp>

  pan::log_NOTICE("int: ", pan::i(10));

  pan::log_INFORMATIONAL("float: ", pan::real(1.23));

  pan::log_INFORMATIONAL("bool: ", pan::b(true));

Unfortunately, in the presence of ATL or MFC - or any other library that has conversion constructors and for which string access shims are defined - the former statements will compile and execute, but will not produce the expected output. Consider the following code:

#include <afx.h>
#include <pantheios/pan.hpp>

  pan::log_NOTICE("int: ", 10);

In a wide-string build in the presence of MFC, then rather than causing a compilation error, the 10 will actually be converted to an instance of CString, via the conversion constructor taking a TCHAR argument!

Obviously this is not desirable, particularly not for a diagnotic logging library! As of 1.0.1 beta 210, there are compile-time constraints in the application layer function templates - log(), log_DEBUG(), etc. - that cause a compile error if any argument is of fundamental type.

Friday, January 7, 2011

Pantheios::Extras::DiagUtil 0.1.1 (alpha 1)

I've just released the first publicly available version - 0.1.1 (alpha 1) - of Pantheios.Extras.DiagUtil; details here.


It allows a user to replace code such as:

 #if defined(_MSC_VER) && \
     defined(_DEBUG)
 # include <crtdbg.h>
 #endif

 int main(int argc, char** argv)
 {
 #if defined(_MSC_VER) && \
     defined(_DEBUG)
  _CrtMemState  memState;

  _CrtMemCheckpoint(&memState);
 #endif

  int result;

  . . .  // main program logic (which must assign to result)

 #if defined(_MSC_VER) && \
     defined(_DEBUG)

  _CrtMemDumpAllObjectsSince(&memState);
 #endif

  return result;
 }

with:

 #include <pantheios/extras/diagutil.hpp>

 int program(int argc, char** argv)
 {
  . . . // main program logic

  return EXIT_SUCCESS;
 }

 int main(int argc, char** argv)
 {
  return pantheios::extras::diagutil::
           main_leak_trace::invoke(argc, argv, program);
 }

or, if your program is written in C, with:

 #include <pantheios/extras/diagutil.h>

 int program(int argc, char** argv)
 {
  . . . // main program logic

  return EXIT_SUCCESS;
 }

 int main(int argc, char** argv)
 {
  return pantheios_extras_diagutil_main_leak_trace_invoke(
           argc, argv, program);
  }

The immediate advantate is clear: substantially improved transparency in your application code. There are three secondary advantages:
  • you do not need to explicitly conditionally include crtdbg.h
  • the library can be enhanced in the future to work with other compiler-extensions, without requiring any changes to your code
  • you do not have to avoid the use of return statements in your main program logic, and to remember to assign to result

More memory-tracing functionality will appear in forthcoming releases.

Tuesday, January 4, 2011

pantheios_be_file_flush()

The newly released Pantheios 1.0.1 beta 208 contains an enhancement to be.file: the addition of a new API function pantheios_be_file_flush().

  int pantheios_be_file_flush(int backEndId);

The function takes a single int argument, backEndId, representing the identifier of the specific be.file back-end instance to be flushed, or PANTHEIOS_BEID_ALL, to apply to all be.file back-end instances.

The function returns 0 on success, or a status code representing failure in one or more be.file back-end instances.

Pantheios 1.0.1 beta 208 released

Pantheios 1.0.1 beta 208 is released. It contains:

  • addition of new API function, pantheios_be_file_flush(), to be.file.
  • fix of defect in be.file, whereby interpretation of date/time format specifiers in its file path - a feature added in 1.0.1 beta 197 - failed to add 1900 to year and 1 to month in be.file's
  • changes in names of status codes, removing word ERROR, and replacing with FAILURE.
  • removal of all remaining vestigial uses of magic numbers - principally -1 and -2 - from exception-catch clauses in core and several back-ends, and replacement with suitable status codes (e.g. PANTHEIOS_INIT_RC_UNSPECIFIED_FAILURE).
  • non-functional enhancements to be.N, in preparation for new functionality in a forthcoming release
  • added a new FAQ item (#19), which explains how to use get Pantheios to compile the libraries when using Microsoft Visual C++'s -Zc:wchar_t- flag.
  • removed -D_CRT_SECURE_NO_DEPRECATE from all Visual C++ (8+) makefiles, since all Pantheios (and supporting STLSoft) files are now compatible with Microsoft's "safe string" library.
  • added a new example, example.cpp.util.strdup, illustrating use of utility functions pantheios::util::strdup_throw() and pantheios::util::strdup_nothrow().
  • removed all include/pantheios/extras/* files, which will (re-)appear in separate package distributions henceforth.

Monday, November 8, 2010

Wide String Shims for std::exception

The new release of STLSoft supports seamless use of exceptions with Pantheios (and FastFormat)  in wide-string builds; described on this post on the STLSoft project blog.

Pantheios 1.0.1 beta 198 released: new i and xi inserters

The latest release of Pantheios includes two new inserters, pantheios::i and pantheios::xi. The former is a typedef for the pantheios::integer inserter class, and may be used interchangeably with it:

  #include <pantheios/inserters/i.hpp>
  #include <pantheios/pan.hpp>
  int n = 10;

  pan::log_DEBUG("i=", pan::i(n));
  pan::log_DEBUG("i=", pan::i(n, -10));
  pan::log_DEBUG("i=", pan::i(n, -10, pan::fmt::hex));

produces the same output (and effectively the same binary) as:

  #include <pantheios/inserters/integer.hpp>
  #include <pantheios/pan.hpp>

  int n = 10;

  pan::log_DEBUG("i=", pan::integer(n));
  pan::log_DEBUG("i=", pan::integer(n, -10));
  pan::log_DEBUG("i=", pan::integer(n, -10, pan::fmt::hex));

The latter is actually a new class, and is used specifically for inserting integers in hexadecimal form, optionally specifying minimum width:

  #include <pantheios/inserters/xi.hpp>
  #include <pantheios/pan.hpp>
  int n = 16;

  pan::log_DEBUG("i=", pan::xi(n));
  pan::log_DEBUG("i=", pan::xi(n, -10));


The (hopefully obvious) advantage to both these new inserter types is that they're more succinct. There are more to come ...

Tuesday, November 2, 2010

User blogs about "Pantheios Basics"

Just to let you know, a user has kindly posted a tutorial Pantheios logging library - basic blog entry, which covers the basics of obtaining, installing, and using the Pantheios library.

I've just scanned it, and it looks like it covers quite a lot of stuff.


I'll read it fully soon, and post any more relevant news.


Thanks, Son DN!