github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/src/third_party/google-glog/doc/.svn/text-base/glog.html.svn-base (about) 1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> 2 3 <html> 4 <head> 5 <title>How To Use Google Logging Library (glog)</title> 6 7 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 8 <link href="http://www.google.com/favicon.ico" type="image/x-icon" 9 rel="shortcut icon"> 10 <link href="designstyle.css" type="text/css" rel="stylesheet"> 11 <style type="text/css"> 12 <!-- 13 ol.bluelist li { 14 color: #3366ff; 15 font-family: sans-serif; 16 } 17 ol.bluelist li p { 18 color: #000; 19 font-family: "Times Roman", times, serif; 20 } 21 ul.blacklist li { 22 color: #000; 23 font-family: "Times Roman", times, serif; 24 } 25 //--> 26 </style> 27 </head> 28 29 <body> 30 31 <h1>How To Use Google Logging Library (glog)</h1> 32 <small>(as of 33 <script type=text/javascript> 34 var lm = new Date(document.lastModified); 35 document.write(lm.toDateString()); 36 </script>) 37 </small> 38 <br> 39 40 <h2> <A NAME=intro>Introduction</A> </h2> 41 42 <p><b>Google glog</b> is a library that implements application-level 43 logging. This library provides logging APIs based on C++-style 44 streams and various helper macros. 45 You can log a message by simply streaming things to LOG(<a 46 particular <a href="#severity">severity level</a>>), e.g. 47 48 <pre> 49 #include <glog/logging.h> 50 51 int main(int argc, char* argv[]) { 52 // Initialize Google's logging library. 53 google::InitGoogleLogging(argv[0]); 54 55 // ... 56 LOG(INFO) << "Found " << num_cookies << " cookies"; 57 } 58 </pre> 59 60 <p>Google glog defines a series of macros that simplify many common logging 61 tasks. You can log messages by severity level, control logging 62 behavior from the command line, log based on conditionals, abort the 63 program when expected conditions are not met, introduce your own 64 verbose logging levels, and more. This document describes the 65 functionality supported by glog. Please note that this document 66 doesn't describe all features in this library, but the most useful 67 ones. If you want to find less common features, please check 68 header files under <code>src/glog</code> directory. 69 70 <h2> <A NAME=severity>Severity Level</A> </h2> 71 72 <p> 73 You can specify one of the following severity levels (in 74 increasing order of severity): <code>INFO</code>, <code>WARNING</code>, 75 <code>ERROR</code>, and <code>FATAL</code>. 76 Logging a <code>FATAL</code> message terminates the program (after the 77 message is logged). 78 Note that messages of a given severity are logged not only in the 79 logfile for that severity, but also in all logfiles of lower severity. 80 E.g., a message of severity <code>FATAL</code> will be logged to the 81 logfiles of severity <code>FATAL</code>, <code>ERROR</code>, 82 <code>WARNING</code>, and <code>INFO</code>. 83 84 <p> 85 The <code>DFATAL</code> severity logs a <code>FATAL</code> error in 86 debug mode (i.e., there is no <code>NDEBUG</code> macro defined), but 87 avoids halting the program in production by automatically reducing the 88 severity to <code>ERROR</code>. 89 90 <p>Unless otherwise specified, glog writes to the filename 91 "/tmp/<program name>.<hostname>.<user name>.log.<severity level>.<date>.<time>.<pid>" 92 (e.g., "/tmp/hello_world.example.com.hamaji.log.INFO.20080709-222411.10474"). 93 By default, glog copies the log messages of severity level 94 <code>ERROR</code> or <code>FATAL</code> to standard error (stderr) 95 in addition to log files. 96 97 <h2><A NAME=flags>Setting Flags</A></h2> 98 99 <p>Several flags influence glog's output behavior. 100 If the <a href="http://code.google.com/p/google-gflags/">Google 101 gflags library</a> is installed on your machine, the 102 <code>configure</code> script (see the INSTALL file in the package for 103 detail of this script) will automatically detect and use it, 104 allowing you to pass flags on the command line. For example, if you 105 want to turn the flag <code>--logtostderr</code> on, you can start 106 your application with the following command line: 107 108 <pre> 109 ./your_application --logtostderr=1 110 </pre> 111 112 If the Google gflags library isn't installed, you set flags via 113 environment variables, prefixing the flag name with "GLOG_", e.g. 114 115 <pre> 116 GLOG_logtostderr=1 ./your_application 117 </pre> 118 119 <!-- TODO(hamaji): Fill the version number 120 <p>By glog version 0.x.x, you can use GLOG_* environment variables 121 even if you have gflags. If both an environment variable and a flag 122 are specified, the value specified by a flag wins. E.g., if GLOG_v=0 123 and --v=1, the verbosity will be 1, not 0. 124 --> 125 126 <p>The following flags are most commonly used: 127 128 <dl> 129 <dt><code>logtostderr</code> (<code>bool</code>, default=<code>false</code>) 130 <dd>Log messages to stderr instead of logfiles.<br> 131 Note: you can set binary flags to <code>true</code> by specifying 132 <code>1</code>, <code>true</code>, or <code>yes</code> (case 133 insensitive). 134 Also, you can set binary flags to <code>false</code> by specifying 135 <code>0</code>, <code>false</code>, or <code>no</code> (again, case 136 insensitive). 137 <dt><code>stderrthreshold</code> (<code>int</code>, default=2, which 138 is <code>ERROR</code>) 139 <dd>Copy log messages at or above this level to stderr in 140 addition to logfiles. The numbers of severity levels 141 <code>INFO</code>, <code>WARNING</code>, <code>ERROR</code>, and 142 <code>FATAL</code> are 0, 1, 2, and 3, respectively. 143 <dt><code>minloglevel</code> (<code>int</code>, default=0, which 144 is <code>INFO</code>) 145 <dd>Log messages at or above this level. Again, the numbers of 146 severity levels <code>INFO</code>, <code>WARNING</code>, 147 <code>ERROR</code>, and <code>FATAL</code> are 0, 1, 2, and 3, 148 respectively. 149 <dt><code>log_dir</code> (<code>string</code>, default="") 150 <dd>If specified, logfiles are written into this directory instead 151 of the default logging directory. 152 <dt><code>v</code> (<code>int</code>, default=0) 153 <dd>Show all <code>VLOG(m)</code> messages for <code>m</code> less or 154 equal the value of this flag. Overridable by --vmodule. 155 See <a href="#verbose">the section about verbose logging</a> for more 156 detail. 157 <dt><code>vmodule</code> (<code>string</code>, default="") 158 <dd>Per-module verbose level. The argument has to contain a 159 comma-separated list of <module name>=<log level>. 160 <module name> 161 is a glob pattern (e.g., <code>gfs*</code> for all modules whose name 162 starts with "gfs"), matched against the filename base 163 (that is, name ignoring .cc/.h./-inl.h). 164 <log level> overrides any value given by --v. 165 See also <a href="#verbose">the section about verbose logging</a>. 166 </dl> 167 168 <p>There are some other flags defined in logging.cc. Please grep the 169 source code for "DEFINE_" to see a complete list of all flags. 170 171 <p>You can also modify flag values in your program by modifying global 172 variables <code>FLAGS_*</code> . Most settings start working 173 immediately after you update <code>FLAGS_*</code> . The exceptions are 174 the flags related to destination files. For example, you might want to 175 set <code>FLAGS_log_dir</code> before 176 calling <code>google::InitGoogleLogging</code> . Here is an example: 177 178 <pre> 179 LOG(INFO) << "file"; 180 // Most flags work immediately after updating values. 181 FLAGS_logtostderr = 1; 182 LOG(INFO) << "stderr"; 183 FLAGS_logtostderr = 0; 184 // This won't change the log destination. If you want to set this 185 // value, you should do this before google::InitGoogleLogging . 186 FLAGS_log_dir = "/some/log/directory"; 187 LOG(INFO) << "the same file"; 188 </pre> 189 190 <h2><A NAME=conditional>Conditional / Occasional Logging</A></h2> 191 192 <p>Sometimes, you may only want to log a message under certain 193 conditions. You can use the following macros to perform conditional 194 logging: 195 196 <pre> 197 LOG_IF(INFO, num_cookies > 10) << "Got lots of cookies"; 198 </pre> 199 200 The "Got lots of cookies" message is logged only when the variable 201 <code>num_cookies</code> exceeds 10. 202 203 If a line of code is executed many times, it may be useful to only log 204 a message at certain intervals. This kind of logging is most useful 205 for informational messages. 206 207 <pre> 208 LOG_EVERY_N(INFO, 10) << "Got the " << google::COUNTER << "th cookie"; 209 </pre> 210 211 <p>The above line outputs a log messages on the 1st, 11th, 212 21st, ... times it is executed. Note that the special 213 <code>google::COUNTER</code> value is used to identify which repetition is 214 happening. 215 216 <p>You can combine conditional and occasional logging with the 217 following macro. 218 219 <pre> 220 LOG_IF_EVERY_N(INFO, (size > 1024), 10) << "Got the " << google::COUNTER 221 << "th big cookie"; 222 </pre> 223 224 <p>Instead of outputting a message every nth time, you can also limit 225 the output to the first n occurrences: 226 227 <pre> 228 LOG_FIRST_N(INFO, 20) << "Got the " << google::COUNTER << "th cookie"; 229 </pre> 230 231 <p>Outputs log messages for the first 20 times it is executed. Again, 232 the <code>google::COUNTER</code> identifier indicates which repetition is 233 happening. 234 235 <h2><A NAME=debug>Debug Mode Support</A></h2> 236 237 <p>Special "debug mode" logging macros only have an effect in debug 238 mode and are compiled away to nothing for non-debug mode 239 compiles. Use these macros to avoid slowing down your production 240 application due to excessive logging. 241 242 <pre> 243 DLOG(INFO) << "Found cookies"; 244 245 DLOG_IF(INFO, num_cookies > 10) << "Got lots of cookies"; 246 247 DLOG_EVERY_N(INFO, 10) << "Got the " << google::COUNTER << "th cookie"; 248 </pre> 249 250 <h2><A NAME=check>CHECK Macros</A></h2> 251 252 <p>It is a good practice to check expected conditions in your program 253 frequently to detect errors as early as possible. The 254 <code>CHECK</code> macro provides the ability to abort the application 255 when a condition is not met, similar to the <code>assert</code> macro 256 defined in the standard C library. 257 258 <p><code>CHECK</code> aborts the application if a condition is not 259 true. Unlike <code>assert</code>, it is *not* controlled by 260 <code>NDEBUG</code>, so the check will be executed regardless of 261 compilation mode. Therefore, <code>fp->Write(x)</code> in the 262 following example is always executed: 263 264 <pre> 265 CHECK(fp->Write(x) == 4) << "Write failed!"; 266 </pre> 267 268 <p>There are various helper macros for 269 equality/inequality checks - <code>CHECK_EQ</code>, 270 <code>CHECK_NE</code>, <code>CHECK_LE</code>, <code>CHECK_LT</code>, 271 <code>CHECK_GE</code>, and <code>CHECK_GT</code>. 272 They compare two values, and log a 273 <code>FATAL</code> message including the two values when the result is 274 not as expected. The values must have <code>operator<<(ostream, 275 ...)</code> defined. 276 277 <p>You may append to the error message like so: 278 279 <pre> 280 CHECK_NE(1, 2) << ": The world must be ending!"; 281 </pre> 282 283 <p>We are very careful to ensure that each argument is evaluated exactly 284 once, and that anything which is legal to pass as a function argument is 285 legal here. In particular, the arguments may be temporary expressions 286 which will end up being destroyed at the end of the apparent statement, 287 for example: 288 289 <pre> 290 CHECK_EQ(string("abc")[1], 'b'); 291 </pre> 292 293 <p>The compiler reports an error if one of the arguments is a 294 pointer and the other is NULL. To work around this, simply static_cast 295 NULL to the type of the desired pointer. 296 297 <pre> 298 CHECK_EQ(some_ptr, static_cast<SomeType*>(NULL)); 299 </pre> 300 301 <p>Better yet, use the CHECK_NOTNULL macro: 302 303 <pre> 304 CHECK_NOTNULL(some_ptr); 305 some_ptr->DoSomething(); 306 </pre> 307 308 <p>Since this macro returns the given pointer, this is very useful in 309 constructor initializer lists. 310 311 <pre> 312 struct S { 313 S(Something* ptr) : ptr_(CHECK_NOTNULL(ptr)) {} 314 Something* ptr_; 315 }; 316 </pre> 317 318 <p>Note that you cannot use this macro as a C++ stream due to this 319 feature. Please use <code>CHECK_EQ</code> described above to log a 320 custom message before aborting the application. 321 322 <p>If you are comparing C strings (char *), a handy set of macros 323 performs case sensitive as well as case insensitive comparisons - 324 <code>CHECK_STREQ</code>, <code>CHECK_STRNE</code>, 325 <code>CHECK_STRCASEEQ</code>, and <code>CHECK_STRCASENE</code>. The 326 CASE versions are case-insensitive. You can safely pass <code>NULL</code> 327 pointers for this macro. They treat <code>NULL</code> and any 328 non-<code>NULL</code> string as not equal. Two <code>NULL</code>s are 329 equal. 330 331 <p>Note that both arguments may be temporary strings which are 332 destructed at the end of the current "full expression" 333 (e.g., <code>CHECK_STREQ(Foo().c_str(), Bar().c_str())</code> where 334 <code>Foo</code> and <code>Bar</code> return C++'s 335 <code>std::string</code>). 336 337 <p>The <code>CHECK_DOUBLE_EQ</code> macro checks the equality of two 338 floating point values, accepting a small error margin. 339 <code>CHECK_NEAR</code> accepts a third floating point argument, which 340 specifies the acceptable error margin. 341 342 <h2><A NAME=verbose>Verbose Logging</A></h2> 343 344 <p>When you are chasing difficult bugs, thorough log messages are very 345 useful. However, you may want to ignore too verbose messages in usual 346 development. For such verbose logging, glog provides the 347 <code>VLOG</code> macro, which allows you to define your own numeric 348 logging levels. The <code>--v</code> command line option controls 349 which verbose messages are logged: 350 351 <pre> 352 VLOG(1) << "I'm printed when you run the program with --v=1 or higher"; 353 VLOG(2) << "I'm printed when you run the program with --v=2 or higher"; 354 </pre> 355 356 <p>With <code>VLOG</code>, the lower the verbose level, the more 357 likely messages are to be logged. For example, if 358 <code>--v==1</code>, <code>VLOG(1)</code> will log, but 359 <code>VLOG(2)</code> will not log. This is opposite of the severity 360 level, where <code>INFO</code> is 0, and <code>ERROR</code> is 2. 361 <code>--minloglevel</code> of 1 will log <code>WARNING</code> and 362 above. Though you can specify any integers for both <code>VLOG</code> 363 macro and <code>--v</code> flag, the common values for them are small 364 positive integers. For example, if you write <code>VLOG(0)</code>, 365 you should specify <code>--v=-1</code> or lower to silence it. This 366 is less useful since we may not want verbose logs by default in most 367 cases. The <code>VLOG</code> macros always log at the 368 <code>INFO</code> log level (when they log at all). 369 370 <p>Verbose logging can be controlled from the command line on a 371 per-module basis: 372 373 <pre> 374 --vmodule=mapreduce=2,file=1,gfs*=3 --v=0 375 </pre> 376 377 <p>will: 378 379 <ul> 380 <li>a. Print VLOG(2) and lower messages from mapreduce.{h,cc} 381 <li>b. Print VLOG(1) and lower messages from file.{h,cc} 382 <li>c. Print VLOG(3) and lower messages from files prefixed with "gfs" 383 <li>d. Print VLOG(0) and lower messages from elsewhere 384 </ul> 385 386 <p>The wildcarding functionality shown by (c) supports both '*' 387 (matches 0 or more characters) and '?' (matches any single character) 388 wildcards. Please also check the section about <a 389 href="#flags">command line flags</a>. 390 391 <p>There's also <code>VLOG_IS_ON(n)</code> "verbose level" condition 392 macro. This macro returns true when the <code>--v</code> is equal or 393 greater than <code>n</code>. To be used as 394 395 <pre> 396 if (VLOG_IS_ON(2)) { 397 // do some logging preparation and logging 398 // that can't be accomplished with just VLOG(2) << ...; 399 } 400 </pre> 401 402 <p>Verbose level condition macros <code>VLOG_IF</code>, 403 <code>VLOG_EVERY_N</code> and <code>VLOG_IF_EVERY_N</code> behave 404 analogous to <code>LOG_IF</code>, <code>LOG_EVERY_N</code>, 405 <code>LOF_IF_EVERY</code>, but accept a numeric verbosity level as 406 opposed to a severity level. 407 408 <pre> 409 VLOG_IF(1, (size > 1024)) 410 << "I'm printed when size is more than 1024 and when you run the " 411 "program with --v=1 or more"; 412 VLOG_EVERY_N(1, 10) 413 << "I'm printed every 10th occurrence, and when you run the program " 414 "with --v=1 or more. Present occurence is " << google::COUNTER; 415 VLOG_IF_EVERY_N(1, (size > 1024), 10) 416 << "I'm printed on every 10th occurence of case when size is more " 417 " than 1024, when you run the program with --v=1 or more. "; 418 "Present occurence is " << google::COUNTER; 419 </pre> 420 421 <h2> <A name="signal">Failure Signal Handler</A> </h2> 422 423 <p> 424 The library provides a convenient signal handler that will dump useful 425 information when the program crashes on certain signals such as SIGSEGV. 426 The signal handler can be installed by 427 google::InstallFailureSignalHandler(). The following is an example of output 428 from the signal handler. 429 430 <pre> 431 *** Aborted at 1225095260 (unix time) try "date -d @1225095260" if you are using GNU date *** 432 *** SIGSEGV (@0x0) received by PID 17711 (TID 0x7f893090a6f0) from PID 0; stack trace: *** 433 PC: @ 0x412eb1 TestWaitingLogSink::send() 434 @ 0x7f892fb417d0 (unknown) 435 @ 0x412eb1 TestWaitingLogSink::send() 436 @ 0x7f89304f7f06 google::LogMessage::SendToLog() 437 @ 0x7f89304f35af google::LogMessage::Flush() 438 @ 0x7f89304f3739 google::LogMessage::~LogMessage() 439 @ 0x408cf4 TestLogSinkWaitTillSent() 440 @ 0x4115de main 441 @ 0x7f892f7ef1c4 (unknown) 442 @ 0x4046f9 (unknown) 443 </pre> 444 445 <p> 446 By default, the signal handler writes the failure dump to the standard 447 error. You can customize the destination by InstallFailureWriter(). 448 449 <h2> <A name="misc">Miscellaneous Notes</A> </h2> 450 451 <h3><A NAME=message>Performance of Messages</A></h3> 452 453 <p>The conditional logging macros provided by glog (e.g., 454 <code>CHECK</code>, <code>LOG_IF</code>, <code>VLOG</code>, ...) are 455 carefully implemented and don't execute the right hand side 456 expressions when the conditions are false. So, the following check 457 may not sacrifice the performance of your application. 458 459 <pre> 460 CHECK(obj.ok) << obj.CreatePrettyFormattedStringButVerySlow(); 461 </pre> 462 463 <h3><A NAME=failure>User-defined Failure Function</A></h3> 464 465 <p><code>FATAL</code> severity level messages or unsatisfied 466 <code>CHECK</code> condition terminate your program. You can change 467 the behavior of the termination by 468 <code>InstallFailureFunction</code>. 469 470 <pre> 471 void YourFailureFunction() { 472 // Reports something... 473 exit(1); 474 } 475 476 int main(int argc, char* argv[]) { 477 google::InstallFailureFunction(&YourFailureFunction); 478 } 479 </pre> 480 481 <p>By default, glog tries to dump stacktrace and makes the program 482 exit with status 1. The stacktrace is produced only when you run the 483 program on an architecture for which glog supports stack tracing (as 484 of September 2008, glog supports stack tracing for x86 and x86_64). 485 486 <h3><A NAME=raw>Raw Logging</A></h3> 487 488 <p>The header file <code><glog/raw_logging.h></code> can be 489 used for thread-safe logging, which does not allocate any memory or 490 acquire any locks. Therefore, the macros defined in this 491 header file can be used by low-level memory allocation and 492 synchronization code. 493 Please check <code>src/glog/raw_logging.h.in</code> for detail. 494 </p> 495 496 <h3><A NAME=plog>Google Style perror()</A></h3> 497 498 <p><code>PLOG()</code> and <code>PLOG_IF()</code> and 499 <code>PCHECK()</code> behave exactly like their <code>LOG*</code> and 500 <code>CHECK</code> equivalents with the addition that they append a 501 description of the current state of errno to their output lines. 502 E.g. 503 504 <pre> 505 PCHECK(write(1, NULL, 2) >= 0) << "Write NULL failed"; 506 </pre> 507 508 <p>This check fails with the following error message. 509 510 <pre> 511 F0825 185142 test.cc:22] Check failed: write(1, NULL, 2) >= 0 Write NULL failed: Bad address [14] 512 </pre> 513 514 <h3><A NAME=syslog>Syslog</A></h3> 515 516 <p><code>SYSLOG</code>, <code>SYSLOG_IF</code>, and 517 <code>SYSLOG_EVERY_N</code> macros are available. 518 These log to syslog in addition to the normal logs. Be aware that 519 logging to syslog can drastically impact performance, especially if 520 syslog is configured for remote logging! Make sure you understand the 521 implications of outputting to syslog before you use these macros. In 522 general, it's wise to use these macros sparingly. 523 524 <h3><A NAME=strip>Strip Logging Messages</A></h3> 525 526 <p>Strings used in log messages can increase the size of your binary 527 and present a privacy concern. You can therefore instruct glog to 528 remove all strings which fall below a certain severity level by using 529 the GOOGLE_STRIP_LOG macro: 530 531 <p>If your application has code like this: 532 533 <pre> 534 #define GOOGLE_STRIP_LOG 1 // this must go before the #include! 535 #include <glog/logging.h> 536 </pre> 537 538 <p>The compiler will remove the log messages whose severities are less 539 than the specified integer value. Since 540 <code>VLOG</code> logs at the severity level <code>INFO</code> 541 (numeric value <code>0</code>), 542 setting <code>GOOGLE_STRIP_LOG</code> to 1 or greater removes 543 all log messages associated with <code>VLOG</code>s as well as 544 <code>INFO</code> log statements. 545 546 <h3><A NAME=windows>Notes for Windows users</A></h3> 547 548 <p>Google glog defines a severity level <code>ERROR</code>, which is 549 also defined in <code>windows.h</code> . You can make glog not define 550 <code>INFO</code>, <code>WARNING</code>, <code>ERROR</code>, 551 and <code>FATAL</code> by defining 552 <code>GLOG_NO_ABBREVIATED_SEVERITIES</code> before 553 including <code>glog/logging.h</code> . Even with this macro, you can 554 still use the iostream like logging facilities: 555 556 <pre> 557 #define GLOG_NO_ABBREVIATED_SEVERITIES 558 #include <windows.h> 559 #include <glog/logging.h> 560 561 // ... 562 563 LOG(ERROR) << "This should work"; 564 LOG_IF(ERROR, x > y) << "This should be also OK"; 565 </pre> 566 567 <p> 568 However, you cannot 569 use <code>INFO</code>, <code>WARNING</code>, <code>ERROR</code>, 570 and <code>FATAL</code> anymore for functions defined 571 in <code>glog/logging.h</code> . 572 573 <pre> 574 #define GLOG_NO_ABBREVIATED_SEVERITIES 575 #include <windows.h> 576 #include <glog/logging.h> 577 578 // ... 579 580 // This won't work. 581 // google::FlushLogFiles(google::ERROR); 582 583 // Use this instead. 584 google::FlushLogFiles(google::GLOG_ERROR); 585 </pre> 586 587 <p> 588 If you don't need <code>ERROR</code> defined 589 by <code>windows.h</code>, there are a couple of more workarounds 590 which sometimes don't work: 591 592 <ul> 593 <li>#define <code>WIN32_LEAN_AND_MEAN</code> or <code>NOGDI</code> 594 <strong>before</strong> you #include <code>windows.h</code> . 595 <li>#undef <code>ERROR</code> <strong>after</strong> you #include 596 <code>windows.h</code> . 597 </ul> 598 599 <p>See <a href="http://code.google.com/p/google-glog/issues/detail?id=33"> 600 this issue</a> for more detail. 601 602 <hr> 603 <address> 604 Shinichiro Hamaji<br> 605 Gregor Hohpe<br> 606 <script type=text/javascript> 607 var lm = new Date(document.lastModified); 608 document.write(lm.toDateString()); 609 </script> 610 </address> 611 612 </body> 613 </html>