Skip to content

Migration from standard log package

goodsign edited this page Feb 3, 2013 · 1 revision

Migration from the log package to seelog is a common task for those who want to start using seelog in an application which already utilizes logging functionality via the standard pkg.

Incompatibility

Seelog concepts are different from the standard log concepts, and thus they are not compatible.

Example #1: there is no analog to log.Printf(..) in seelog, because Printf doesn't carry any log level information, so if we are migrating, it is not clear, what should we replace log.Printf with. It may be seelog.Infof or seelog.Debugf or any other.

Example #2: log.Panicf(..), which creates the message according to format and panics using the formatted message as the panic text. In seelog, one call to any of the log funcs may produce several messages with different formats, depending on the config. So, it's not clear, what to use as the panic text if we are talking about seelog analog to Panicf.

Example #3: log.SetPrefix. seelog just cannot have any analog to that, because one call to any log func (e.g. Debug) may produce several messages with different formats, so it doesn't make sense to have one such global func. Also, one of the seelog core principles is to avoid configuration via code. All configuration is done via config files. So such function would break current seelog concepts.

Conclusion

There is no function in current version of standard log package (go1.0.3), that may have any analog in seelog. So seelog actually cannot have any of 'standard log pkg compatibility features'.

Migration

Despite the fact that actually you cannot replace log with seelog and have the same behavior (they are just incompatible, as stated above), you may want to automate the migration from log to seelog. Our recommendation here is to create a replacement script that would reflect your project specifics and your plans on using seelog.

Example migration script

Here is a python script performing some replacements in multiple files for several log package funcs. It can be used as an example or extended to create a script for your own needs.

import os, sys,shutil,re

changeDir= './test'
openFlags = 'rb'
writeFlags = 'r+b'
encoding = 'utf-8'
backupPostfix = '.backup'

goFilesRx = r'.+\.go$'

patterns = [

(re.compile(ur'''(?P<before>import[\s\S]*?)"log"''', re.U | re.M), 
            ur'''\g<before>log "github.com/cihub/seelog"'''), # change import

(re.compile(ur'''log.Print(?P<after>.*?)''', re.U), 
            ur'''log.Info\g<after>'''), # Print -> Info

(re.compile(ur'''log.Println(?P<after>.*?)''', re.U),
            ur'''log.Info\g<after>'''), # Println -> Info

(re.compile(ur'''log.Printf(?P<after>.*?)''', re.U),
            ur'''log.Infof\g<after>'''), # Printf -> Infof

(re.compile(ur'''(?P<ws>[\t ]*)log.Panic\((?P<values>.*?)\)''', re.U),
            ur'''\g<ws>log.Info(\g<values>)\n\g<ws>panic(fmt.Sprint(\g<values>))'''), # Panic -> Info + panic(...)

(re.compile(ur'''(?P<ws>[\t ]*)log.Panicf\((?P<values>.*?)\)''', re.U),
            ur'''\g<ws>log.Infof(\g<values>)\n\g<ws>panic(fmt.Sprint(\g<values>))'''), # Panicf -> Info + panic(...)

# ... and so on

]

def rewriteFile(fl, text):
   fl.read() # To preserve file creation date
   fl.seek(0)
   fl.write(text.encode(encoding))
   fl.truncate()

def replacePatterns(filePath, backup):
   # Open file and get its contents
   input = open(filePath, openFlags)
   fileText = unicode(input.read(), encoding)
   input.close()

   found = False
   # Make replacements for all patterns
   for pc in patterns:
      origRx = pc[0]
      replRx = pc[1]
      replacedText = re.sub(origRx, replRx, fileText)
      if fileText != replacedText:
         found = True
      fileText = replacedText

   # If any replacements were made, write the changed file
   if found:
      if backup:
         bckName = filePath + backupPostfix
         shutil.copy2(filePath, bckName)

      outF = open(filePath,writeFlags)
      rewriteFile(outF, fileText)
      outF.close()

def replaceFunc(a, dir, files):
   for f in files:
      fPath = dir + '/' + f
      if re.search(goFilesRx, f, re.U) and os.path.isfile(fPath):
         replacePatterns(fPath, True)

os.path.walk(changeDir, replaceFunc, 3)