Newsletters



Sawmill Newsletter

  July 15, 2008



Welcome to the Sawmill Newsletter!

You're receiving this newsletter because during the downloading or purchase of Sawmill, you checked the box to join our mailing list. If you wish to be removed from this list, please send an email, with the subject line of "UNSUBSCRIBE" to newsletter@sawmill.net .


News

SAWMILL SALE! For July only, all Sawmill upgrades are half price. Upgrade your Sawmill 6 (or earlier) license to Sawmill 7, for 50% of the usual price; or upgrade your existing Sawmill 7 installation to a higher tier (e.g., Professional to Enterprise) or to a larger number of profiles, for half the usual cost. Orders in our online store will automatically show the discount; or you may claim the discount on any purchase order. Hurry; this offer ends July 31!

Sawmill 7.2.15 shipped on May 16, 2008. This is a minor "bug fix" release, and it is free to existing Sawmill 7 users.  It is recommended for anyone who is experiencing problems with Sawmill 7.2.14 or earlier. You can download it from http://sawmill.net/download.html .

Sawmill 8 has entered "alpha" stage. That means that we have completed development of all features, and Sawmill 8 will ship (8.0.0) when all known bugs are fixed. Major features of Sawmill 8 include support for Oracle and Microsoft SQL Server databases, real-time reporting, a completely redesigned web interface, better multi-processor and multi-core support, and role-based authentication control. A "beta" version will be publicly available when all major bugs are fixed, probably in the next few weeks. Watch sawmill.net for the beta announcement!

This issue of the Sawmill Newsletter describes techniques for adding Sawmill users (users with access to the Sawmill web interface) automatically, using command-line scripting.


Get the Most out of Sawmill with Professional Services

Looking to get more out of your statistics from Sawmill? Running short on time, but need the information now to make critical business decisions? Our Professional Service Experts are available for just this situation and many others. We will assist in the initial installation of Sawmill using best practices; work with you to integrate and configure Sawmill to generate reports in the shortest possible time. We will tailor Sawmill to your environment, create a customized solution, be sensitive to your requirements and stay focused on what your business needs are. We will show you areas of Sawmill you may not even be aware of, demonstrating these methods will provide you with many streamlined methods to get you the information more quickly. Often you'll find that Sawmill's deep analysis can even provide you with information you've been after but never knew how to reach, or possibly never realized was readily available in reports. Sawmill is an extremely powerful tool for your business, and most users only exercise a fraction of this power. That's where our experts really can make the difference. Our Sawmill experts have many years of experience with Sawmill and with a large cross section of devices and business sectors. Our promise is to very quickly come up with a cost effective solution that fits your business, and greatly expand your ROI with only a few hours of fee based Sawmill Professional Services. For more information, a quote, or to speak directly with a Professional services expert contact consulting@flowerfire.com.



Tips & Techniques:
Adding Users Automatically With Salang Scripting

Sawmill's "Create Many Profiles" feature makes it easy to add new profiles automatically, by embedding Sawmill in a larger environment, and calling the "create many profiles" Salang script to generate or regenerate many similar profiles from a single template. See the November 15, 2007 Sawmill Newsletter for a discussion of Create Many Profiles.

But what if you want to have a separate user for each profile, and want that to be created automatically too? This might be useful in a web hosting environment, where you want each user to be able to log into Sawmill to see only the reports for their own domains; so for each customer, you would create a Sawmill user, and then give it permission to access its own domains (profiles), and finally give the customer a direct link to the Sawmill web interface (or, including Sawmill as a "tab" in a larger interface).

This can be done using Salang scripting. This newsletter includes an example script, and how to use it.

The Add User Script

Here is a script which adds a user (or modifies an existing user):


  # This script adds a non-administrative user with access to one profile.
  #
  # Usage: sawmill -dp miscellaneous.add_user v.username <username> v.password <password> v.profile <profile>

  {=
 
  # Create the user node for v.username (in the "users" node, i.e., the users.cfg file in LogAnalysisInfo),
  # if it doesn't already exist
  set_subnode_value('users', v.username, '');

  # Set the username to v.username
  set_subnode_value('users.' . v.username, 'username', v.username);

  # Set the password.  This computes the MD5 checksum of v.password, and puts it in the password_checksum of the user node
  set_subnode_value('users.' . v.username, 'password_checksum', md5_digest(v.password) );

  # Make this a non-administrative user
  set_subnode_value('users.' . v.username, 'administrator', false);

  # Add a "profiles" subnode in the user record, where we can list the profile accessible to this user.
  set_subnode_value('users.' . v.username, 'profiles', '');

  # Give the user access to one profile: the one specified by v.profile
  set_subnode_value('users.' . v.username . '.profiles', v.profile, true);

  # Save the users node (users.cfg)
  save_node('users');

  # Display the new (or modified) users node
  echo(node_as_string('users.' . v.username));
 
  =}



LogAnalysisInfo/miscellaneous/add_user.cfv

To use this script, put it in the miscellaneous folder, which is in the LogAnalysisInfo folder of your Sawmill installation. Then, from the command line, run this on Windows (assuming Sawmill is installed at C:\Program Files\Sawmill 7):

  C:
  cd Program Files\Sawmill 7
  SawmillCL -dp miscellaneous.add_user v.username username v.password password v.profile profile

Or on other operating systems, run this command line:

  cd sawmill-install-dir
  ./sawmill -dp miscellaneous.add_user v.username username v.password password v.profile profile

(./sawmill may need to be qualified with the version number, e.g., ./sawmill7.2.15).

That will create a new user whose username is username, whose password is password, who is a non-administrator, and who has access to one profile, called profile. The profile parameter must be the internal name of the profile, i.e., the name of the file as it appears in LogAnalysisInfo\profiles, without the .cfg extension. So, if your have a profile CFG file in LogAnalysisInfo\profiles\jennys_site.cfg, you would use "v.profile jennys_side" in the command line.

By embedding a call to this script in a larger environment, you can automatically create a username every time you add a new customer. By calling it again with the same username, you can change their password, or add access to new profiles.


Advanced Topic: Understanding The Script

You don't need to understand the script to use it, but if you want to modify it, or do some Salang scripting of your own, you'll need to know how it works, and why. This section dissects the script in detail, to explain what each piece does. This section assumes familiarity with computer programming. The Salang section of the Sawmill Technical Manual (click Help in the upper right of any Sawmill installation) provides a more technical and complete description of Salang.
1. The {= and =} tags.

The {= before the script and =} after the scripts are used in a CFV ("configuration value") file to indicate a section of Salang code. Without these tags, the entire CFV file is treated as a literal string. When {= and =} are present, the section between them is compiled and executed, and its result is inserted in the resulting string. In this case, we're not using the result string at all--we just want to have an effect when we run the script--so the entire script is embedded in {= =}.

2. Comments start with #

All lines beginning with # are comments, and are ignored by Salang. These are for documentation purposes only, and have no effect on the code.

3.  set_subnode_value('users', v.username, '');

The set_subnode_value() function in Salang sets a value within a node. A node is a general Salang data structure, which is similar to a perl hash (or, to a lesser degree, a C structure). Unlike perl hashes or C structures, however, Salang nodes can reside in memory, or on disk, or both. Referring to a node by the name 'users' indicates that it is a top-level node called 'users'; and because there is a file called "users.cfg" in LogAnalysisInfo, Sawmill automatically equates the two, and this function operates on the node whose content is described by the file users.cfg. Because that is the file which contains Sawmill User information, this line operates directly on the user information file. The contents of the file is loaded into memory automatically, when the node is referenced, and the modifications are made to the in-memory copy. The changes are not saved to disk until save_node() is called, below.

So, this operates on the "users" node, and in this case it is setting the value of a subnode. The name of the subnode is the value of v.username, which is a variable specified by the v.username command-line parameter. v.username is also a node: it is the "username" subnode of the top-level "v" node, which does not have an on-disk counterpart, so remains in memory. The "v" node is often used for temporary variables, but has no particular significance to Salang--it could have been called x.username, as long as both the command line and the script called it that.

The last parameter to set_subnode_value(), which specifies the value to assign to the subnode, is empty. So this line sets the subnode whose name is in the variable v.username to "". If the value v.username is "jenny", then a subnode "jenny" will be created in "users" (users.cfg), and set to empty. This creates a new user record, called "jenny."

By the way, this code uses single-quotes ('), but double-quotes (") and backticks (`) are all treated identically by Salang. So the script would work the same if all single quotes were double quotes, or if they were all backticks.

Assuming there were no users before this line ran, the "users" node would look like this after this line:


  users = {
    jenny = ""
  } # users


So, the user record has been created, but has no values in it yet. Note that the file users.cfg has not yet been modified, and won't be until save_node() is called, below.

4.  set_subnode_value('users.' . v.username, 'username', v.username);

This is similar to #2, above. But the first parameter uses the concatenation operator (.) to concatentate the value of the v.username variable to the literal string "users.". If the value of v.username was "jenny", the concatenation would be "users.jenny", so that is the node we are operating on. In node names (like "users.jenny"), a dot is a hierarchy divider, so "users.jenny" refers to the subnode "jenny" of the node "users". So this line sets the subnode "username" of the node "users.jenny" to the value of v.username. This adds a "username" parameter, with value "jenny", to the user record for "jenny".

The "users" node would look like this after this line:


  users = {
    jenny = {
      username = "jenny"
    } # jenny
  } # users


5.  set_subnode_value('users.' . v.username, 'password_checksum', md5_digest(v.password) );

As with #3, this sets a subnode of the user node (users.jenny). In this case, it's setting the password_checksum node. For security, the password is not stored plain-text in the users node, so it is first encoded using the built-in function md5_digest(), before being written to the password_checksum node.

The "users" node would look like this after this line:


  users = {
    jenny = {
      username = "jenny"
      password_checksum = "4ed9407630eb1000c0f6b63842defa7d"
    } # jenny
  } # users


6.  set_subnode_value('users.' . v.username, 'administrator', false);

As with #3 and #4, this sets a subnode of the user node (users.jenny). Here, it sets the "administrator" node to false, indicating that this user is not an administrator.

The "users" node would look like this after this line:


  users = {
    jenny = {
      username = "jenny"
      password_checksum = "4ed9407630eb1000c0f6b63842defa7d"
      administrator = false
    } # jenny
  } # users


7.  set_subnode_value('users.' . v.username, 'profiles', '');

As with #3, #4, and #5 this sets a subnode of the user node. Here, it creates a "profiles" subnode of the users node. This node is empty at first, but can be filled with one or more profile names, indicating which profiles the user may access.

The "users" node would look like this after this line:


  users = {
    jenny = {
      username = "jenny"
      password_checksum = "4ed9407630eb1000c0f6b63842defa7d"
      administrator = false
      profiles = ""
    } # jenny
  } # users


8.  set_subnode_value('users.' . v.username . '.profiles', v.profile, true);

This sets a subnode of the "profiles" node created in step 6. It uses the concatenation operator to concatenate "users.", the value of v.username, and ".profiles"; if v.profile is "jenny" (as above), this string is "users.jenny.profiles", which points to the "profiles" subnode of the "jenny" subnode of the "users" node (which is users.cfg in LogAnalysisInfo). This operates on the subnode specified by the value of v.profile. The v.profile value is specified on the command line, so for this example, we'll assume it is "jennys_site". This subnode does not exist, so it is created, and its value is set to true (the third parameter above).

The "users" node would look like this after this line:


  users = {
    jenny = {
      username = "jenny"
      password_checksum = "4ed9407630eb1000c0f6b63842defa7d"
      administrator = false
      profiles = {
        jennys_site = true
      } # profiles
    } # jenny
  } # users


9.  save_node('users');

This saves the node 'users' to its natural position on disk, which is the users.cfg file in LogAnalysisInfo. The content of users.cfg is replaced by the "users" node shown in the box above. After this line, the user modification is complete, and Sawmill will immediately allow logins by the new user and there is no need to restart the service.

10.  echo(node_as_string('users.' . v.username));

This displays to console (standard output) the contents of the subnode specified by v.username, in the "users" node. In the example above, it would display this to console:


  jenny = {
    username = "jenny"
    password_checksum = "4ed9407630eb1000c0f6b63842defa7d"
    administrator = false
    profiles = {
      jennys_site = true
    } # profiles
  } # jenny
 


This provides some feedback of what the script did, allowing you to verify the new or modified user record.

Conclusion

This newsletter presented a simple Salang script, which performs a useful operation. Salang is a fully general programming language, which can be used to do any type of scripting. Sawmill's entire web interface is written in Salang, as are log filters, parsing filters, and many other major components. If you are a programmer, or have a programmer available, you can use Salang to greatly extend the functionality of Sawmill, and to implement your own features in Sawmill.

If you would like assistance in maintaining this script, or in creating scripts for your own, you can also use Sawmill Professional Services. Our experts have a thorough knowledge of Salang, and can create any type of scripts for you. Contact sales@sawmill.net for more information.


[Article revision v1.2]
[ClientID: 46]