darshan-parser.c 6.92 KB
Newer Older
1
/*
2 3 4
 * Copyright (C) 2015 University of Chicago.
 * See COPYRIGHT notice in top-level directory.
 *
5 6
 */

7 8 9 10 11 12 13 14
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <zlib.h>
#include <time.h>
15
#include <stdlib.h>
16
#include <getopt.h>
17
#include <assert.h>
18

19
#include "uthash-1.9.2/src/uthash.h"
20

21
#include "darshan-logutils.h"
22

23 24 25
int main(int argc, char **argv)
{
    int ret;
26
    int i, j;
27
    char *filename;
28
    char tmp_string[4096];
29 30 31 32 33
    darshan_fd fd;
    struct darshan_header header;
    struct darshan_job job;
    struct darshan_record_ref *rec_hash = NULL;
    struct darshan_record_ref *ref;
34 35 36
    int mount_count;
    char** mnt_pts;
    char** fs_types;
37
    time_t tmp_time = 0;
38 39
    char *token;
    char *save;
40
    char buffer[DARSHAN_JOB_METADATA_LEN];
41
    int empty_mods = 0;
42

43 44 45
    /* TODO: argument parsing */
    assert(argc == 2);
    filename = argv[1];
46

47 48
    fd = darshan_log_open(filename, "r");
    if(!fd)
49
    {
50
        fprintf(stderr, "darshan_log_open() failed to open %s\n.", filename);
51 52
        return(-1);
    }
53 54 55

    /* read darshan log header */
    ret = darshan_log_getheader(fd, &header);
56
    if(ret < 0)
57
    {
58 59
        fprintf(stderr, "darshan_log_getheader() failed to read log header.\n");
        darshan_log_close(fd);
60 61 62
        return(-1);
    }

63 64 65 66 67 68 69 70
    /* read darshan job info */
    ret = darshan_log_getjob(fd, &job);
    if(ret < 0)
    {
        fprintf(stderr, "darshan_log_getjob() failed to read job data.\n");
        darshan_log_close(fd);
        return(-1);
    }
71

72 73
    /* get the original command line for this job */
    ret = darshan_log_getexe(fd, tmp_string);
74
    if(ret < 0)
75
    {
76
        fprintf(stderr, "Error: unable to read trailing job information.\n");
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
        darshan_log_close(fd);
        return(-1);
    }

    /* get the mount information for this log */
    ret = darshan_log_getmounts(fd, &mnt_pts, &fs_types, &mount_count);
    if(ret < 0)
    {
        fprintf(stderr, "darshan_log_getmounts() failed to read mount information.\n");
        darshan_log_close(fd);
        return(-1);
    }

    /* read hash of darshan records */
    ret = darshan_log_gethash(fd, &rec_hash);
    if(ret < 0)
    {
        fprintf(stderr, "darshan_log_getmap() failed to read record map.\n");
        darshan_log_close(fd);
96 97 98
        return(-1);
    }

99
    /* print job summary */
100
    printf("# darshan log version: %s\n", header.version_string);
101
    printf("# exe: %s\n", tmp_string);
Philip Carns's avatar
Philip Carns committed
102 103 104
    printf("# uid: %" PRId64 "\n", job.uid);
    printf("# jobid: %" PRId64 "\n", job.jobid);
    printf("# start_time: %" PRId64 "\n", job.start_time);
105
    tmp_time += job.start_time;
106
    printf("# start_time_asci: %s", ctime(&tmp_time));
Philip Carns's avatar
Philip Carns committed
107
    printf("# end_time: %" PRId64 "\n", job.end_time);
108 109
    tmp_time = 0;
    tmp_time += job.end_time;
110
    printf("# end_time_asci: %s", ctime(&tmp_time));
Philip Carns's avatar
Philip Carns committed
111 112
    printf("# nprocs: %" PRId64 "\n", job.nprocs);
    printf("# run time: %" PRId64 "\n", job.end_time - job.start_time + 1);
113 114 115 116 117
    for(token=strtok_r(job.metadata, "\n", &save);
        token != NULL;
        token=strtok_r(NULL, "\n", &save))
    {
        char *key;
118 119 120 121 122 123 124 125 126 127 128 129 130 131
        char *value;
        /* NOTE: we intentionally only split on the first = character.
         * There may be additional = characters in the value portion
         * (for example, when storing mpi-io hints).
         */
        strcpy(buffer, token);
        key = buffer;
        value = index(buffer, '=');
        if(!value)
            continue;
        /* convert = to a null terminator to split key and value */
        value[0] = '\0';
        value++;
        printf("# metadata: %s = %s\n", key, value);
132
    }
133

134 135 136 137 138 139 140
    /* print breakdown of each log file component's contribution to file size */
    printf("\n# log file component sizes (decompressed)\n");
    printf("# -------------------------------------------------------\n");
    printf("# header: %zu bytes\n", sizeof(struct darshan_header));
    printf("# job data: %zu bytes\n", sizeof(struct darshan_job));
    printf("# record table: %zu bytes\n", header.rec_map.len);
    for(i=0; i<DARSHAN_MAX_MODS; i++)
141
    {
142
        if(header.mod_map[i].len)
143
        {
144 145
            printf("# %s module: %zu bytes\n", darshan_module_names[i],
                header.mod_map[i].len);
146
        }
147 148
    }

149 150 151
    /* print table of mounted file systems */
    printf("\n# mounted file systems (mount point and fs type)\n");
    printf("# -------------------------------------------------------\n");
152 153
    for(i=0; i<mount_count; i++)
    {
154
        printf("# mount entry:\t%s\t%s\n", mnt_pts[i], fs_types[i]);
155
    }
156

157
    DARSHAN_PRINT_HEADER();
158

159
    for(i=0; i<DARSHAN_MAX_MODS; i++)
160
    {
161 162
        void *rec_p = NULL;
        darshan_record_id rec_id;
163

164 165
        /* skip modules not present in log file */
        if(header.mod_map[i].len == 0)
166
        {
167 168 169
            empty_mods++;
            if(empty_mods == DARSHAN_MAX_MODS)
                printf("# no module data available.\n");
170

171
            continue;
172 173
        }

174 175
        /* skip modules with no defined logutil handlers */
        if(!mod_logutils[i])
176
        {
177 178 179
            fprintf(stderr, "Warning: no log utility handlers defined "
                "for module %s, SKIPPING\n", darshan_module_names[i]);
            continue;
180 181
        }

182
        /* this module has data to be parsed and printed */
183

184
        /* TODO: do modules print header of what each counter means??? */
185

186 187 188 189 190
        /* loop over each of this module's records and print them */
        while ((ret = mod_logutils[i]->log_get_record(fd, &rec_p, &rec_id)) == 1)
        {
            char *mnt_pt = NULL;
            char *fs_type = NULL;
Philip Carns's avatar
Philip Carns committed
191

192 193 194
            /* get the pathname for this record */
            HASH_FIND(hlink, rec_hash, &rec_id, sizeof(darshan_record_id), ref);
            assert(ref);
195

196 197
            /* get mount point and fs type associated with this record */
            for(j=0; j<mount_count; j++)
198
            {
199 200 201 202 203 204
                if(strncmp(mnt_pts[j], ref->rec.name, strlen(mnt_pts[j])) == 0)
                {
                    mnt_pt = mnt_pts[j];
                    fs_type = fs_types[j];
                    break;
                }
205
            }
206 207 208 209
            if(!mnt_pt)
                mnt_pt = "UNKNOWN";
            if(!fs_type)
                fs_type = "UNKNOWN";
210

211 212 213
            /* print the corresponding module data for this record */
            mod_logutils[i]->log_print_record(rec_p, ref->rec.name,
                mnt_pt, fs_type);
214

215 216
            /* NOTE: we have to free the given file record data */
            free(rec_p);
217 218
        }

219
        if(ret < 0)
220
        {
221 222 223 224 225
            fprintf(stderr, "Error: failed to parse module %s data\n",
                darshan_module_names[i]);
            fflush(stderr);
            darshan_log_close(fd);
            return(-1);
226 227 228
        }
    }

229 230
    /* free mount info */
    for(i=0; i<mount_count; i++)
231
    {
232 233
        free(mnt_pts[i]);
        free(fs_types[i]);
234
    }
235
    if(mount_count > 0)
236
    {
237 238
        free(mnt_pts);
        free(fs_types);
239 240
    }

241
    darshan_log_close(fd);
242

243
    return(0);
244
}